bash - bash 从文件中删除文本块
问题描述
假设我有一个带有文本行的输入文件:
line 1
line 2
line 3
line 4
line 2
现在假设我想检查我的输入文件是否包含
line 2
line 3
并删除该文本块(如果找到)。这将给出:
line 1
line 4
line 2
请注意,我不想只删除每次出现的line 2
or line 3
; 但前提是它们一个接一个被发现。(实际上,我想检查一个 5 行的块,而不仅仅是两个占位符之间的任何代码块,但让我们保持示例简单)。
我调查了一下awk
,但这很快就变得复杂了(我还没有准备好;因为我觉得这不是正确的方法,并且会爆炸成 5 行......)
awk '/line 2/ {if (line0) {print line0; line0=""}; line0=$0}' input.txt
解决方案
使用 GNU awk 进行多字符 RS 和 RT 的一种方法:
$ awk -v RS='(^|\n)line 2\nline 3\n' '{ORS=(RT ~ /^\n/ ? "\n" : "")} 1' file
line 1
line 4
line 2
使用任何 awk:
$ cat file
line 2
line 3
line 1
line 2
line 3
line 4
line 2
line 3
$ awk '
{ rec = rec $0 RS }
END {
rec = RS rec
gsub(/\nline 2\nline 3\n/,RS,rec)
gsub(/^\n|\n$/,"",rec)
print rec
}
' file
line 1
line 4
以上假设您想使用正则表达式进行匹配,因为这就是您发布的代码所做的。如果您想进行文字字符串匹配,那么通过一些按摩也可以做到:
$ cat tst.awk
{ rec = rec $0 RS }
END {
while ( beg = index(RS rec,RS block RS) ) {
out = out substr(RS rec,1,beg-1)
rec = substr(RS rec,beg+length(block)+2)
}
print substr(out rec,2)
}
$ awk -v block='line 2\nline 3' -f tst.awk file
line 1
line 4