Преобразование текста с помощью «sed» или «awk» - PullRequest
3 голосов
/ 08 марта 2012

У меня очень большой набор входных данных, который выглядит примерно так:

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? Если да, то как я могу это сделать?

Ответы [ 3 ]

5 голосов
/ 08 марта 2012

Вот мой файл label.awk:

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

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

1

Для вызова:

awk -f label.awk data.txt
2 голосов
/ 08 марта 2012

Одно решение с использованием sed:

Содержимое script.sed:

## 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/
}

Содержимое infile:

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:...
2 голосов
/ 08 марта 2012

Вы можете использовать awk следующим образом:

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