在BASH中找到匹配文件后,如何删除上面的两行?
我有一个包含以下数据的文件:在BASH中找到匹配文件后,如何删除上面的两行?,bash,awk,sed,grep,Bash,Awk,Sed,Grep,我有一个包含以下数据的文件: 123 456 789 当我找到匹配项789时,我想删除上面两行(123和456)。是否可以使用sed或awk进行此操作?请帮助将文件加载到内存中(因此对于大文件来说不是最好的选择) 将文件加载到内存中,检查最后一行是否匹配,如果是,则删除前两行,打印结果与其他一些答案不同,此脚本不会将整个文件加载到内存中,因此它对大文件非常有效,并且假设您至少有3行 #n 1{ N h n :loop ${ /7
当我找到匹配项789时,我想删除上面两行(123和456)。是否可以使用sed或awk进行此操作?请帮助将文件加载到内存中(因此对于大文件来说不是最好的选择)
将文件加载到内存中,检查最后一行是否匹配,如果是,则删除前两行,打印结果与其他一些答案不同,此脚本不会将整个文件加载到内存中,因此它对大文件非常有效,并且假设您至少有3行
#n
1{
N
h
n
:loop
${
/789/! {
x
p
g
}
p
}
$!{
H
g
P
s/^[^\n]*\n//
h
n
b loop
}
}
如果将此保存为s.sed,则可以运行
sed -f s.sed file
如果最后一行匹配789,它将删除最后一行之前的两行
输入:
123
456
789
abc
123
456
789
123
456
abc
输出:
789
abc
789
123
456
abc
输入:
123
456
789
abc
123
456
789
123
456
abc
输出:
789
abc
789
123
456
abc
输入:
123
456
789
abc
123
456
789
123
456
abc
输出:
789
abc
789
123
456
abc
解释
#n
抑制正常输出。在第一行,匹配1
,我们在下一行附加N
,并用h
将其复制到保留空间。然后我们用n
转到下一行,然后启动:循环
如果当前行是由$
拾取的最后一行,那么我们检查它是否与789不匹配,在这种情况下,我们使用x
交换图案和保留空间,使用p
打印新图案空间,然后使用g
将保留空间复制到图案空间上。最后我们打印出最后一行
如果当前行不是最后一行。我们使用H
将当前行附加到保持空间,然后将保持空间复制到模式空间。我们使用P
打印模式空间的第一行,然后使用s/^[^\n]*\n/
删除第一行。我们将其复制回等待空间,转到下一行,并使用b loop
awk重复循环以拯救
awk '{a[NR]=$0} END{for(i=1;i<=NR;i++) if(a[i+1] a[i+2]!~/789/) print a[i]}' test.1
输出
使用ed
,标准编辑器:
ed -s file <<< $'3,$g/789/-2,.d\nw'
说明:
3,$g/789/
将标记从第3行*到文件末尾的所有与/789/
匹配的行;然后,对于每个标记行,它将执行以下命令:
-2,.d
这意味着:删除范围-2,.
,即从当前(-2
)上方的两行开始并在此处结束(
)的范围
然后w
表示写入文件。如果您不想写入文件而想先尝试,而是想在终端上打印(出于测试目的),请将w
命令替换为、p
和Q
,如下所示:
ed -s file <<< $'3,$g/789/-2,.d\n,p\nQ'
将生成一个空文件,并且
123
456
789
123
789
你会得到一个错误
*该范围从第3行开始,只是为了防止模式出现在前两行时出错,这可能适合您(GNU sed):
在模式空间中保留一个3行的移动窗口,如果第三行是所需的模式,则删除前两行。文件是否包含1,2。等等。还有?几个匹配的情况如何(删除表start unitl last match或仅删除匹配的前两行?如果匹配在第一行或第二行怎么办?是的,我的文件包含序列号numbers@NeronLeVelu我只想在匹配后删除前两行,并且匹配必须在最后一行。对“是否可能”的回答总是“是”所以,不要问这个问题。编辑你的问题,以显示一些更具代表性的示例输入和预期输出。根据你目前发布的内容,一个解决方案会产生明显的预期效果。这会为我打印所有行。哪个版本的sed(这是posix版本,所以GNU sed需要--posix
)GNU-sed版本4.1.5
使用--posix
进行了尝试,但仍然获得了所有的行数?你是对的,我之前测试没有序列号,在codeFYI中添加了这个,接受的ed
回答也会将整个文件加载到内存中。回答得好!:)执行-2
的可能性很大。不久前我还和ed一起玩过,但(据我记忆所及)我最终觉得我不喜欢我需要将程序传递给stdin的事实。。但是这个答案展示了ed
的一个很好的用例。我基本上喜欢sed
答案,但是我认为sed
不是适合这个的工具,因为它在这里的灵活性非常有限。如果OP想要删除图案上方的20条线怎么办?如果你问我,使用awk和缓冲那些n行应该被删除。这也不需要将整个文件存储在内存中,但它提供了按照您的意愿指定n行以删除的灵活性。我的意思是这就是awk
的意义所在。