我可以使用sed的多行匹配逻辑来删除一系列行之间的所有行吗?
我一直在尝试各种表达式的组合,但是运气不好。
这是一个示例文件(“ creatures.txt”):
START TAG
species: swallowtail butterfly flying
legs
wings
head
END TAG
START TAG
species: common lizard running
legs
tail
head
END TAG
START TAG
species: peacock butterfly resting
legs
wings
head
END TAG
START TAG
species: blackbird flying
legs
wings
head
END TAG
我想执行以下操作:
因此,使用上面的示例文件,结果将是:
START TAG
END TAG
START TAG
species: common lizard
legs
tail
head
END TAG
START TAG
END TAG
START TAG
species: blackbird
legs
wings
head
END TAG
谢谢, 詹姆斯。
答案 0 :(得分:1)
赞:
sed '/START TAG/{N;/butterfly/{:a;/END TAG/!{N;ba};d}}' file
说明:
# Enter block when 'START TAG' is found
/START TAG/ {
N # Append next line to the pattern buffer
# Enter block when 'butterfly' is found
/butterfly/ {
:a # Create a label (could be also :foo)
# Enter block unless 'END TAG' is found
/END TAG/! {
N # Append next line to pattern buffer
ba # branch back to label :a
}
# Once 'END TAG' is found
d # Delete the pattern buffer
}
}
PS:可以使用经过稍微修改的版本来保留START
/ END
标签:
sed '/START/{p;N;/butterfly/{:a;/END/!{N;ba};s/.*\n//}}' file
答案 1 :(得分:1)
每当您发现自己说sed multiline
时,都在使用错误的工具。 sed用于在单独的行上执行s / old / new,仅此而已。除此之外,您还应该使用awk。
$ cat tst.awk
{ rec = (rec=="" ? "" : rec ORS) $0 }
/END/ {
numLines = split(rec,lines,ORS)
print (lines[2] ~ /butterfly/ ? lines[1] ORS lines[numLines] : rec)
rec = ""
}
$ awk -f tst.awk file
START TAG
END TAG
START TAG
species: common lizard running
legs
tail
head
END TAG
START TAG
END TAG
START TAG
species: blackbird flying
legs
wings
head
END TAG
以上内容可以在任何UNIX框上的任何shell中使用任何awk进行工作,如果/稍后您的需求发生变化时可以清晰,简单,强大且易于修改,以查看或打印每条记录或任何组合中的任何其他行每行或整个记录中的值。例如,要生成仅记录该生物具有翅膀的记录的CSV:
$ cat tst.awk
{ rec = (rec=="" ? "" : rec ORS) $0 }
/END/ {
numLines = split(rec,lines,ORS)
if ( lines[4] == "wings" ) {
sub(/species: /,"",lines[2])
for (i=2; i<numLines; i++) {
printf "%s%s", lines[i], (i<(numLines-1) ? "," : ORS)
}
}
rec = ""
}
$ awk -f tst.awk file
swallowtail butterfly flying,legs,wings,head
peacock butterfly resting,legs,wings,head
blackbird flying,legs,wings,head
和您可能想要做的其他事情一样琐碎且一致。