2012-03-07 68 views
3

我有一個非常大的輸入設置,看起來像這樣的文字:轉化與「sed的」或「的awk」

Label: foo, Other text: text description... 
    <insert label> Item: item description... 
    <insert label> Item: item description... 
Label: bar, Other text:... 
    <insert label> Item:... 
Label: baz, Other text:... 
    <insert label> Item:... 
    <insert label> Item:... 
    <insert label> Item:... 
... 

我想改變這個拉出標籤名稱(例如"foo")並用實際標籤替換以下行上的標籤"<insert label>"

Label: foo, Other text: text description... 
    foo Item: item description... 
    foo Item: item description... 
Label: bar, Other text:... 
    bar Item:... 
Label: baz, Other text:... 
    baz Item:... 
    baz Item:... 
    baz Item:... 
... 

這可以用sed或awk或其他unix工具來完成嗎?如果是這樣,我該怎麼做?

回答

2

一個使用sed解決方案:

內容的 script.sed

內容 infile
## When line beginning with the 'label' string. 
/^Label/ { 
    ## Save content to 'hold space'. 
    h 

    ## Get the string after the label (removing all other characters) 
    s/^[^ ]*\([^,]*\).*$/\1/ 

    ## Save it in 'hold space' and get the original content 
    ## of the line (exchange contents). 
    x 

    ## Print and read next line. 
    b 
} 
###--- Commented this wrong behaviour ---###  
#--- G 
#--- s/<[^>]*>\(.*\)\n\(.*\)$/\2\1/ 

###--- And fixed with this ---### 
## When line begins with '<insert label>' 
/<insert label>/ { 
    ## Append the label name to the line. 
    G 

    ## And substitute the '<insert label>' string with it. 
    s/<insert label>\(.*\)\n\(.*\)$/\2\1/ 
} 

Label: foo, Other text: text description... 
    <insert label> Item: item description... 
    <insert label> Item: item description... 
Label: bar, Other text:... 
    <insert label> Item:... 
Label: baz, Other text:... 
    <insert label> Item:... 
    <insert label> Item:... 
    <insert label> Item:... 

運行它想:

sed -f script.sed infile 

而且結果:

Label: foo, Other text: text description... 
    foo Item: item description... 
    foo Item: item description... 
Label: bar, Other text:... 
    bar Item:... 
Label: baz, Other text:... 
    baz Item:... 
    baz Item:... 
    baz Item:... 
+0

出現錯誤:'sed:2:script.sed:invalid command code I''。我使用不同版本的'sed'嗎? – Manish 2012-03-07 22:32:21

+0

@Manish:是的。忽略匹配字符串的情況是GNU擴展。已經修改程序以匹配(包括大小寫)確切的單詞。 – Birei 2012-03-07 22:34:10

+0

現在可以使用,但如果文件中沒有「」行,則不適用。我已將最後一行更改爲'/ <插入標籤> /!s/\ n。* //; s/<插入標籤> \(。* \)\ n \(。* \)$/\ 2 \ 1 /'來處理。 (另外,讓我們特別匹配「<插入標籤>」,文件中可能會有其他這樣的「標籤」。) – Manish 2012-03-07 23:19:23

2

您可以用awk這樣的:

awk '$1=="Label:" {label=$2; sub(/,$/, "", label);} 
    $1=="<insert" && $2=="label>" {$1=" "; $2=label;} 
    {print $0;}' file 
+0

如果」重新錨定模式,你不妨使用'sub'而不是'gsu B'。您不需要單引號內的續行。 – 2012-03-08 01:29:03

+0

@glennjackman:非常感謝您的建議和編輯。欣賞它。 – anubhava 2012-03-08 02:53:18

5

這裏是我的label.awk文件:

/^Label:/ { 
    label = $2 
    sub(/,$/, "", label) 
} 

/<insert label>/ { 
    sub(/<insert label>/, label) 
} 

1 

要調用:

awk -f label.awk data.txt