ファイルに次の内容が含まれている場合:
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'