最初の一致を含む行の上のn行前のすべての行を削除します。

最初の一致を含む行の上のn行前のすべての行を削除します。

ファイルに次の内容が含まれている場合:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9

これで、ファイルに次の内容のみが含まれるように、「5行目」の前に2行以上ある行を削除するにはどうすればよいですか?

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に他の2行が含まれていることを意味します。

そして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'

関連情報