删除包含第一个匹配项的行上方 n 行之前的所有行

删除包含第一个匹配项的行上方 n 行之前的所有行

如果文件包含以下内容:

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}truen达到时将变为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'

相关内容