パターンに一致するn番目の行と次のN行を抽出します。

パターンに一致するn番目の行と次のN行を抽出します。

ファイルに規則的に繰り返されるパターンを含む大容量ファイルがありますが、特定の値が発生した後に特定のパターンのみを抽出し、次の値を抽出したいと思います。窒素いいですね。
ここに例がありますが、前の数字はmembers of the group実際には存在しません。

入力する:

1 members of the group
...
...
2 members of the group
...
...
...
n members of the group
...
...
...

出力:

85 members of the group
...
...
...
...
...

(ゲーム85と次の5行)

答え1

方法は次のとおりですawk

awk -vN=85 -vM=5 'BEGIN{c=0}
/PATTERN/{c++
{if (c==N) {l=NR;last=NR+M}}
}{if (NR<=last && NR>=l) print}' infile

Nどこに窒素最初の行は次の行の数とPATTERN一致します。M次の場合にカウンタを設定します。窒素行3で一致するものが見つかったら、行番号を保存します。次に、現在から+NRまで行を印刷します。NR中サイズ


記録によると、sedgnu sed構文)の使用方法は次のとおりです。

sed -nE '/PATTERN/{x;/\n{84}/{x;$!N;$!N;$!N;$!N;$!N;p;q};s/.*/&\n/;x}' infile

これは計算にアーカイブスペースを使用します。
一致する行が現れるたびに、PATTERNeはxバッファを変更し、その行があるかどうかを確認します。N-1\nバッファに改行文字を保持します。検査が成功するとx再び変更され、次の項目がインポートされます。中サイズ$!Nコマンドを使用してpパターンスペースを印刷し、quitsを印刷します。
それ以外の場合は、\n予約済みスペースに別のewline文字を追加してからx再度変更します。
このソリューションはすぐに面倒になる可能性があるため、あまり便利ではありません。中サイズは大きな数値で、スクリプトをprintf書くには少し-fuが必要ですsed(パターンは言うまでもなく、sedスペースを制限するためにいくつかのsを使用します)。

答え2

(exec <file.txt; grep -m 85 'PATTERN' | tail -n 1; head -n 5)

もちろん、必要に応じて数字を調整できます。

からman grep

   -m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines.  If the  input  is
          standard  input  from a regular file, and NUM matching lines are
          output, grep ensures that the standard input  is  positioned  to
          just  after the last matching line before exiting, regardless of
          the presence of trailing context lines.  This enables a  calling
          process  to resume a search.

grep上記のコマンドは、この機能を正しく機能させるためにサブシェルを使用し、STDINを目的のファイルに設定することによってこの機能を利用します。その後、最終(85番目)のインスタンスキャプチャを使用しtail -n 1て、別の呼び出しで必要なコンテキスト行を取得できますhead

このコマンドを使用すると、知るファイルには85以上のインスタンスがあります。PATTERN;この場合は完璧に動作します。

その場合可能少なく、コマンドに少し調整が必要です。現在の状態で要求されたものよりも一致するものが少ない場合は、末尾のコンテキスト行なしで最終的な一致を印刷します。

答え3

主に正規表現を理解しawkて使用しない場合は、sed次のようにします。

  • grep行番号を含むパターンを見つけるために使用されます。 ( -n)
  • 85番目の一致を取得するには、およびhead/tailまたはを使用してください(参照sedここ)
  • 検疫旅行番号Nを使用してくださいcut
  • headまたはtail(または)を再度使用して、sed元のファイルのN行目と次の5行を取得します。

これらすべてを1行にまとめることができます。汚れて遅いですが、最小限のツールセットで動作します。

はい

以下は rkhunter.log ファイルを検索し、3 番目に表示される「basename」と次の 4 行を表示します。

 /var/log$ tail rkhunter.log -n +$(grep -n 'basename' rkhunter.log|cut -d: -f1|tail -n +3|head -1)| head -5

編集する

私は@Wildcardの答えを見て、変換が元のソリューションよりも使いやすくなりました-mgrepだからここに次のような別の答えがあります。grep -m

/var/log$ grep -m 3 -A 4 'basename'  rkhunter.log | tail -5

答え4

これは私のbashで動作します。

{ T=85; N=5; c=0; while read line ; do echo "$line" | grep -c "members of the group" > /dev/null && c=$(($c+1)) ; [[ $c -eq $T ]] && { echo "$line"; break ;} ; done ; head -n $N ; } < input_file

関連情報