検索パターンの前に<N>
th行だけを印刷しようとしています。 grep -B<N>
は、検索パターンの前にすべての<N>
行を出力します。検索パターンの後に<N>
th行のみを出力できるawkコード here を見ました。
awk 'c&&!--c;/pattern/{c=N}' file
これを変更して、pattern
に一致する各行の前に<N>
th行のみを印刷する方法は?たとえば、ここに私の入力ファイルがあります
...
...
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で実行しようとしています
行のバッファを使用する必要があります。
これを試してみてください:
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
valueを検索する正規表現に設定します。
buffer
はN
要素の配列です。それは行を格納するために使用されます。パターンが見つかるたびに、パターンの前のN
th行が印刷されます。
そのコードは前の行では機能しません。一致したパターンの前にラインを取得するには、すでに処理されたラインを何らかの方法で保存する必要があります。 awk
には連想配列しかないため、awk
でやりたいことを同じように簡単に行う方法は考えられないので、Perlのソリューションを次に示します。
_Perl -ne 'Push @lines,$_; print $lines[0] if /PAT/; shift(@lines) if $.>LIM;' file
_
PAT
を一致させたいパターンに、LIM
を行数に変更します。たとえば、foo
が出現する前に5行目を出力するには、次のように実行します。
_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
行があります。tac file | awk 'c&&!--c;/pattern/{c=N}' | tac
しかし、これは、互いにN行以内に複数の一致がある場合の「フォワード」ユースケースと同じ省略です。
また、実行中のプロセスから入力がパイプ処理されている場合はあまり機能しませんが、入力ファイルが完全で拡張されていない場合は、これが最も簡単な方法です。
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 [〜#〜]の異なる値に対して変更する必要があることです:
N =の場合:
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
したがって、[〜#〜] n [〜#〜]の値を大きくすると、スクリプトファイルを準備してsed
に渡すことができますが、すぐに煩雑になります。