パターンのn番目のオカレンスを検索し、パターンの後にk行を印刷する方法を探しています。この場合、awk
はgrep
よりもうまく機能すると思いますが、適切に行う方法がわかりません...
次のテキストファイルがあるとします。
Draft
blablablabla
tralalalalala
Draft
blablablabla
tralalalalala
Draft
important line 1
important line 2
Draft
blablablabla
tralalalalala
この場合 n=3
およびk=2
、パターン「ドラフト」の3回目の出現に続く2行を印刷したいと思います。私の特定のケースでは、nとkは異なる場合があります。
これを行う簡単な方法ですか?
grep
とtail
を使用して、これを実現できます。
$ n=3
$ k=2
$ grep -m "$n" -A "$k" 'Draft' input.txt | tail -n "$k"
important line 1
important line 2
$
Grepの-m "$n"
オプションは、n
番目の一致後に停止するように指定し、-A "$k"
は、各一致の後にk
行を出力するようにgrepに指示します。次に、これをtail -b "$k"
にパイプして、それらのk
行のみを出力します。
awk:3番目と4番目の「ドラフト」行の間の行を印刷します。
awk -v n=3 '/Draft/ { p = (++num == n) ; next }; p' file
行うべき最適化があります:4番目のドラフトが表示されたら終了します。
awk
経由
awk -v "k=2" -v "n=3" \
'/^Draft/ {i++}
i==n-1 && x==0 {x++;next}
x>=1 && x<=k {print;x++}
x>k {exit}' foo
/^Draft/ {i++}
インクリメントi
to count Draft
i==n-1 && x==0 {x++; next}
n
ndがDraft
に出現する行をスキップし、x
を設定して、n
nd Draft
の後の最初の行を出力します。x>=1 && x<=k {print;x++}
次のk
行を出力しますx>k {exit}
そして終了sed -ne'/^\(.*\n\)*Draft *$/G' \
-e's/\n/&/3;t$' -e'N;D;:$' \
-e's///g;//!n;N;G;s/\n//2' \
-etq -e/.$/b$ -e:q -e'p;q' <in >out
important line 1
important line 2