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

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

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

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パターンの前の行が印刷されます。

答え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-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 行以内に複数の一致がある場合、これは「forwards」の使用例と同じ省略になります。

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

答え4

を使用した別の方法sed

のために1 = 1 です:

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

のために2倍

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

のために2倍この場合、1行目は次のようになりますN-1パターン スペース内の行を読み込んでN;P;Dサイクルを開始します。別の行を読み取り、パターン スペース内の最後の行が一致する場合は、パターン スペースの最初の行を印刷して削除し、新しいサイクルを開始します。

欠点は、異なる値に合わせて変更する必要があることです。いいえ:

のために3 位:

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

のために4人:

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

しかし、より大きな値になるとすぐに面倒になりますいいえスクリプト ファイルを用意して に渡すことができますsed

関連情報