删除前一行到匹配字符串?

时间:2014-07-27 08:56:48

标签: bash sed

如何删除匹配模式的上一行?

或者

与之相反:

sed -n '/pattern/{g;1!p;};h'

7 个答案:

答案 0 :(得分:2)

你可以恢复文件然后删除matche模式之后的行(这很简单),然后还原结果,这里是代码:

tail -r|sed '/pattern/{n;d;}'|tail -r

答案 1 :(得分:1)

使用tac | sed | tac(Linux / Solaris),然后匹配模式后的下一行:)

答案 2 :(得分:1)

对于"相对复杂的"围绕搜索表达式导航,ed可能是一个很好的解决方案(评论不是命令的一部分):

ed testfile << EOF
/r.*o/                        # Search the pattern
-1d                           # delete one line above
w                             # write
EOF

以下是一个示例(使用<<<\n作为单行写入):

sh$ cat testfile
john
paul
george
ringo
sh$ ed testfile <<< $'/r.*o/\n-1d\nw'
23
ringo
16
sh$ cat testfile
john
paul
ringo

答案 3 :(得分:1)

sed是一个很好的工具,可以在一行上进行简单的替换,其他任何东西只需使用awk:

$ cat file
here is a
a bad line before
a good line
in a file

$ awk 'NR==FNR{if (/good/) del[NR-1]; next} !(FNR in del)' file file
here is a
a good line
in a file

您可以使用上述惯用法删除给定模式之前和/或之后的任意数量的行,例如删除给定目标之前的3行和2行:

$ cat file
-5
-4
-3
-2
-1
target
+1
+2
+3
+4
+5
$
$ awk 'NR==FNR{if (/target/) for (i=-3;i<=2;i++) del[NR+i]; next} !(FNR in del)' file file
-5
-4
+3
+4
+5

或将目标留在原地,只删除周围的线条:

$ awk 'NR==FNR{if (/target/) for (i=-3;i<=2;i++) if (i!=0) del[NR+i]; next} !(FNR in del)' file file
-5
-4
target
+3
+4
+5

一切都非常清晰,琐碎,可扩展......

答案 4 :(得分:1)

这可能适合你(GNU sed):

 sed '$!N;/\n.*pattern/!P;D' file

保持2行窗口并测试其中第二行的图案。如果图案存在,则不打印第一行。

答案 5 :(得分:0)

只有当行数大于1且模式不在最后一行时才会有效。

sed -n '/pattern/ { h; b }; 1 { h; b }; ${ H }; x; p' file

更好地使用awk

awk '!/pattern/ && NR > 1 { print p } { p = $0 } END { if (NR) print p }' file

答案 6 :(得分:0)

这是另一个awk

awk '/pattern/ {f=1} !f&&NR>1 {print p} {p=$0;f=0} END {print p}' file

tac awk版本:

tac file | awk '1; /pattern/ {getline}' | tac

PS getline通常应该避免,因为它有很多陷阱,所以这就是:

tac file | awk '!p||NR!=p+1; /pattern/ {p=NR}' | tac