如果文件包含以下内容:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
如何删除“第 5 行”之前两行以上的行,以便文件现在仅包含以下内容?
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
答案1
ed
使用- 支持地址偏移可能会更简单:
printf '%s\n' '/Line 5/-2,$p' | ed -s file
或(就地修改文件)
printf '%s\n' '1,/Line 5/-3d' 'wq' | ed -s file
答案2
通过首先反转输入行,可以更容易地解决此类问题。例如:
$ tac ip.txt | awk '1; /Line 5/{n=3} n && !--n{exit}' | tac
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
n && !--n{exit}
true
当n
达到时将变为0
.在这种情况下,这意味着该行包含Line 5
后跟另外两行。
和sed
:
tac ip.txt | sed '/Line 5/{n; n; q}' | tac
笔记:如果存在多个匹配项,上述解决方案将不起作用,因为它将匹配文件中的最后一个匹配项。这是一种解决方法:
awk '!f && /Line 5/{print p2 ORS p1; f=1} f; {p2=p1; p1=$0}' ip.txt
答案3
如果你的文件少于 10,000 行,你可以使用这个
grep -B2 -A9999 'test test' file
答案4
使用pcregrep
:
$ pcregrep -M "(.*\n){2}.*Line 5(.*\n)*" file
使用awk
:
$ awk -v var=2 '/Line 5/{n=NR; for(i=n-var;i<n;) print ar[i++]}
!n{ar[NR]=$0}n'