ファイル内のテキストは次のとおりです:

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/;" 

これは基本的に、ファイルを空白行で区切られたチャンクに分割し、正規表現に一致するチャンクのみを出力することを意味します。

コメント

回答

他の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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です