ファイル内のテキストは次のとおりです。
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
「42B」をgrepして、上記のテキストから次のような出力を取得する必要があります。
Pseudo name=Apple
Code=42B
state=fault
grep
/ awk
/ を使用してこれを達成する方法について誰にもアイデアがありますsed
か?
ファイル内のテキストは次のとおりです。
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
「42B」をgrepして、上記のテキストから次のような出力を取得する必要があります。
Pseudo name=Apple
Code=42B
state=fault
grep
/ awk
/ を使用してこれを達成する方法について誰にもアイデアがありますsed
か?
回答:
と awk
awk -v RS='' '/42B/' file
RS=
入力レコードの区切り文字を改行から空白行に変更します。レコード内のいずれかのフィールドにレコードが含まれている場合/42B/
。
''
(ヌル文字列)は、POSIXに従って空白行を表すために使用されるマジック値です。
場合RSがヌルである、その後レコードは、以下からなる配列によって分離され、
<newline>
加えて一つ以上の空白行、先頭または末尾の空白行は、入力の先頭または末尾に空のレコードをもたらさないもの、及び<newline>
、常にフィールドセパレータでなければなりませんFSの価値に関係なく。
出力セパレーターは単一の改行のままなので、出力段落は分離されません。出力段落の間に空白行があることを確認するには、出力レコード区切り文字を2つの改行に設定します。
awk -v RS='' -v ORS='\n\n' '/42B/' file
FILENAME
)ファイル名のためにそのことを回避するのに問題が含有するものとして、それは使用のリダイレクトには悪い考えではありません=
かで始まる-
(またはもの-
)、一貫性のあるエラーメッセージになり、そしてことを回避するには、実行中awk
または実行入力ファイルを開けない場合は、他のリダイレクト。
データが常にその前後の行になるように構造化されていると仮定すると、grepの-A
(after)および-B
(before)スイッチを使用して、一致する前の1行とその後の1行を含めるように指示できます。
$ grep -A 1 -B 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault
検索語の前後に同じ行数が必要な場合は、-C
(コンテキスト)スイッチを使用できます。
$ grep -C 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault
複数の行を一致させるときにより厳密にしたい場合は、ツールを使用して、pcregrep
複数の行にわたってパターンを一致させることができます。
$ pcregrep -M 'Pseudo.*\n.*42B.*\nstate.*' sample.txt
Pseudo name=Apple
Code=42B
state=fault
上記のパターンは次のように一致します。
-M
-複数行'Pseudo.*\n.*42B.*\nstate.*'
-最初の文字列が単語で始まり"Pseudo"
、行末までの\n
任意の文字、文字列までの"42B"
任意の文字、行末までの任意の文字(\n
)、文字列が続く文字列のグループに一致します"state"
任意の文字が続きます。-C
と同じ場合-A
、(コンテキスト)をショートカットとして使用できます-B
。
おそらくawkで同様の簡単な方法がありますが、perlでは次のようになります。
cat file | perl -ne 'BEGIN { $/="\n\n" }; print if $_ =~ /42B/;'
基本的には、ファイルを空白行で区切られたチャンクに分割し、正規表現に一致するチャンクのみを印刷するということです。
末尾の空行のない他のperlソリューション:
perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo
例
% perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo
Pseudo name=Apple
Code=42B
state=fault
% cat foo
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
perl -00 -ne 'print if /42B/' file
。