假设我有一个包含文本行的输入文件:
line 1
line 2
line 3
line 4
line 2
现在假设我想检查我的输入文件是否包含
line 2
line 3
并删除该文本块(如果找到)。这将给出:
line 1
line 4
line 2
请注意,我不想删除每次出现的line 2
或line 3
;但前提是要一个接一个地找到它们。 (实际上,我要检查一个5行的块,而不仅仅是两个占位符之间的任何代码块,而是让示例保持简单)。
我调查了awk
,但很快就变得复杂了(我还没有准备好;因为我觉得这不是正确的方法,会用5行爆炸……)
awk '/line 2/ {if (line0) {print line0; line0=""}; line0=$0}' input.txt
答案 0 :(得分:3)
使用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
答案 1 :(得分:1)
使用gnu sed
A B C D
Actual Appoint. Month Count
03Feb18 03Feb18 February 2
10Feb18 15Feb18
18Feb18 15Feb18
答案 2 :(得分:1)
不是RxJS
,但是@triplee指出,这在Perl 5中是很简单的。在五行输入文件中,您在上方显示为awk
:
foo.txt
产生所需的三行输出。
说明:
perl -0777 -pe 's{^line 2\nline 3\n}{}gm' foo.txt
使perl以一个字符串的形式读取整个输入(请参见perlrun)。-0777
修饰符使/m
在行首匹配(请参见perlre)。^
也将在文件开头匹配,因此即使行之前没有换行符,您也可以检测到它们。^
,因为\n
与$
之前的{em>匹配,且\n
与/m
修饰符匹配。因此,仅匹配\n
会更容易。感谢this U&L SE answer的Stéphane Chazelas的基础知识。
答案 3 :(得分:0)
这可能对您有用(GNU sed):
sed '/^line 2$/!b;N;/^line 3$/Md;P;D' file
如果一行与字符串line 2
不匹配,请打印该行并开始下一个循环。否则,请添加以下行,如果该行与字符串line 3
相匹配,请删除这两行。否则,打印然后删除第一行并重复。