パターンに一致する各行の前にN行目のみを印刷します。

パターンに一致する各行の前にN行目のみを印刷します。

<N>検索パターンの前の行だけを印刷しようとしています。検索パターンの前のすべての行を印刷しますgrep -B<N><N>awkコードを見ました。ここ<N>検索パターン次の3行目のみ印刷できます。

awk 'c&&!--c;/pattern/{c=N}' file

<N>各行が一致する前に最初の行だけを印刷するように変更するにはどうすればよいですかpattern?たとえば、これは私の入力ファイルです。

...
...
   0.50007496  0.42473932  0.01527831
   0.99997456  0.97033575  0.44364198
Direct configuration=     1
   0.16929051  0.16544726  0.16608723
   0.16984300  0.16855274  0.50171112
...
...
   0.50089841  0.42608090  0.01499159
   0.99982054  0.97154975  0.44403547
Direct configuration=     2
   0.16931296  0.16553376  0.16600890
   0.16999941  0.16847055  0.50170694  
...

2nd line以前の検索文字列を返すコマンドが必要ですDirect configuration。これを実行しようとしています。SUSE Linux

答え1

ラインバッファが必要です。

この試み:

awk -v N=4 -v pattern="example.*pattern" '{i=(1+(i%N));if (buffer[i]&& $0 ~ pattern) print buffer[i]; buffer[i]=$0;}' file

N印刷するパターンの前のN行目に値を設定してください。

pattern検索する正規表現に値を設定します。

buffer要素の配列ですN。行を保存するために使用されます。パターンが見つかるたびに、Nパターンの前の3行目が印刷されます。

答え2

前の行ではコードは機能しません。パターンを一致させる前に行を取得するには、処理された行を何とか保存する必要があります。連想配列だけなので、awk必要な操作を実行するのと同じくらい簡単な方法が考えられないので、awkここにPerlソリューションがあります。

perl -ne 'push @lines,$_; print $lines[0] if /PAT/; shift(@lines) if $.>LIM;' file 

PAT一致させるパターンと行数に変更しますLIM。たとえば、各項目の前に5行目を印刷するには、foo次のようにします。

perl -ne 'push @lines,$_; print $lines[0] if /foo/; shift(@lines) if $.>5;' file 

説明する

  • perl -ne: 入力ファイルを 1 行ずつ読み込み、与えられたスクリプトを-e各行に適用します。
  • push @lines,$_$_現在の行()を配列に追加します@lines
  • print $lines[0] if /PAT/@lines:現在の行が目的のパターンと一致する場合は、配列の最初の要素()を印刷します。$lines[0]
  • shift(@lines) if $.>LIM;$.現在行番号です。制限より大きい場合は、配列から最初の値を削除します@lines。その結果、@lines常に最後LIMの数行が残ります。

答え3

tac file | awk 'c&&!--c;/pattern/{c=N}' | tac

ただし、これは、N行内に複数の一致がある場合は、「転送」ユースケースと同じ省略があります。

実行中のプロセスで入力がパイプされている場合、これはうまく機能しませんが、入力ファイルが完了して大きくならない場合に最も簡単です。

答え4

の代替sed

~のためN=1:

sed '$!N; /.*\n.*pattern/P; D' FILE

~のためN=2

sed '1N; $!N; /.*\n.*\n.*pattern/P; D' FILE

~のためN=2この場合、最初の行は次の行を読みます。N-1パターン空間の行を選択してN;P;Dループを開始します。別の行を読み、パターン空間の最後の行が一致した場合、パターン空間の最初の行を印刷して削除して新しいループを開始します。

欠点は、別の値に変更する必要があることです。窒素:

~のためN=3:

sed '1{N;N}; $!N; /.*\n.*\n.*\n.*pattern/P; D' FILE

~のためN=4:

sed '1{N;N;N}; $!N; /.*\n.*\n.*\n.*\n.*pattern/P; D' FILE

そのため、大きな値の場合でも急速に面倒になります。窒素スクリプトファイルを準備して転送できますsed

関連情報