ファイル内のテキストは次のとおりです:
Pseudo name=Apple Code=42B state=fault Pseudo name=Prance Code=43B state=good
grepする必要があります「42B」で、上記のテキストから次のような出力を取得します。
Pseudo name=Apple Code=42B state=fault
grep
/ awk
/ sed
?
コメント
- この質問に" grep "のタグを付けました。それでは、" grep "ソリューションのみを探していますか?質問では、awk & sedも指定します。それらのタグを追加できますか?昨夜質問を編集したとき、'あなたの意図がわかりませんでした。
- stackoverflow.com/質問/ 12024410 / …
回答
awk
awk -v RS="" "/42B/" file
RS=
を使用すると、入力レコードの区切り文字が変更されます改行から空白行へ。レコードのいずれかのフィールドに/42B/
が含まれている場合はレコードを印刷します。
""
(null文字列)は魔法です空白行を表すために使用される値 POSIXによる:
If RS がnullの場合、レコードは
<newline>
と1つ以上の空白で構成されるシーケンスで区切られます行、先頭または末尾の空白行は、入力の最初または最後に空のレコードをもたらすことはなく、<newline>
は、 FS はです。
出力段落は出力セパレータは単一の改行のままなので、分離されます。出力段落の間に空白行があることを確認するには、出力レコード区切り文字を2つの改行に設定します。
awk -v RS="" -v ORS="\n\n" "/42B/" file
コメント
- +1でエレガントなソリューションを実現します。 'ファイルをリダイレクトする必要はありません…
- 指は自動操縦されていました。
- @jasonwryan(アクセスが必要な場合を除く) awk内のファイル名(
FILENAME
)に対して、'リダイレクトを使用することは悪い考えではありません。これにより、=
または-
で始まる(または-
)と、一貫したエラーメッセージが表示されます。入力ファイルを'開くことができない場合に、awk
の実行や他のリダイレクトの実行を回避します。
回答
データが常に前後の行になるように構造化されていると仮定すると、grepを利用できます-A
(後)と-B
(前)が切り替わり、試合前に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
If複数の行を照合する場合は、より厳密にしたい場合は、ツール pcregrep
を使用して複数行にわたるパターン:
$ pcregrep -M "Pseudo.*\n.*42B.*\nstate.*" sample.txt Pseudo name=Apple Code=42B state=fault
上記のパターンは次のように一致します:
-
-M
-複数行 -
"Pseudo.*\n.*42B.*\nstate.*"
-最初の文字列が"Pseudo"
の後に、行末までの任意の文字\n
が続き、その後に文字列"42B"
までの任意の文字が続きます。行のもう1つの終わり(\n
)の後に、文字列"state"
の後に任意の文字が続きます。
コメント
-
-C
(コンテキスト)は、-A
と-B
が同じ場合、ショートカットとして使用できます。 - @ DavidBaggerman-ありがとう。回答に追加しました。
- なぜ1票を下すのですか?これで質問に答えます。
回答
grep
Unixの一部のフレーバーには、「段落」の-p
フラグがあります。 AIXが行うことはわかっています。
grep -p 42B <myfile>
あなたが求めていることを正確に実行します。YMMVおよびGNUgrepにはこのフラグがありません。
コメント
- -pフラグがあると便利です。特に-vと一緒に使用すると、段落全体を出力から除外できます。
回答
awkでも同様に簡単な方法がありますが、perlでは次のようになります。
cat file | perl -ne "BEGIN { $/="\n\n" }; print if $_ =~ /42B/;"
これは基本的に、ファイルを空白行で区切られたチャンクに分割し、正規表現に一致するチャンクのみを出力することを意味します。
コメント
- これは、オプションと省略形を使用し、の無駄な使用を失うことで簡略化できます
cat
;perl -00 -ne 'print if /42B/' file
回答
他の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
コメント
- または、tripleeがコメントに書いたように、より短い(したがって、より読みやすく):
perl -00 -ne 'print if /42B/' file
。