ブロックを見つける方法は?それともawk / ackを使用する必要がありますか?

ブロックを見つける方法は?それともawk / ackを使用する必要がありますか?

次の情報を含むファイルがあるとします。

...
Entry '234238': some text
  some text
  some text
  some text
Entry '899823': some text
  some text
  some text
Entry '234238': more text
  more text
  more text
Entry '645353': some text
  some text
  some text

特定を抽出したいと思いますEntry '<code>'。たとえば、grep_my_block 'Entry '234238'次のように返す必要があります。

Entry '234238': some text
  some text
  some text
  some text
Entry '234238': more text
  more text
  more text

気づく:

  1. 識別子ブロックは<code>ファイルに複数回現れることがあります。私たちはそのようなブロックをすべて抽出したいと思います。
  2. ブロックは不明な数の行で構成できます。

どのように使用したりgrepこれをawk行うことができますかack

答え1

awk "/^Entry '234238'/ {printline = 1; print; next}
     /^Entry / {printline = 0}
     printline"

答え2

ENTRY="'234238'"
sed -n ':s;/Entry '"$ENTRY"'/{:l;p;n;/^Entry/bs;bl;}' <<\ENTRY
    Entry '234238': some text
        some text
        some text
        some text
    Entry '899823': some text
        some text
        some text
    Entry '234238': more text
        more text
        more text
    Entry '645353': some text
        some text
        some text
#END
ENTRY

出力

Entry '234238': some text
    some text
    some text
    some text
Entry '234238': more text
    more text
    more text

これよりも優れていますawk(私の考えでは)なぜならsed'sストリーム操作。

それは私がやったことの中で最も複雑でないことの一つです。いったん心を食べたらね。これは、GNU拡張正規表現なしで正常に完了した最初の作業です。これは移植性に非常に優れています。

この分岐は2回発生します。アンカーポイントがあります。:s始点と基準点から:l添字です。うまくいくからn演算子は前の行を削除しますsed'sパターン空間新しいものをインポートするとき。

一度sedあなたの検索"$ENTRY"それは設定する支店:lアベル、行を印刷して新しい行を取得します。それからsed新しい行がフレーズで始まることを確認する'Entry'この場合、再分岐します。:sタグを付け、その入力の再スキャンを開始します。"$ENTRY,"それ以外の場合は、次に分岐します。:lアベルそして繰り返すpリント、n内線/check/仕事。

コマンドは次のように要約されます。

until end of file do
    if current line contains "Entry $ENTRY" do
        until next line contains 'Entry' do
            print line
            delete line 
            next line
        done
    done
done

答え3

以下も使用できますpcregrep

pcregrep -M '234238.*(\n((?!Entry).)*)*' inputfile

これにより、単語を含む行から始まり、単語を含む行に234238会うまですべての行が生成されますEntry

サンプル入力の場合、次のものが生成されます。

Entry '234238': some text
  some text
  some text
  some text
Entry '234238': more text
  more text
  more text

答え4

awk質問は行中心なので、使いやすいツールかもしれません。

重複するコードが少ない@HaukeLagingソリューションのバリエーションを使用します。で始まるすべての行はEntryフラグをクリアしますが、目的の特定の項目のヘッダーには対応するフラグが設定されます。このフラグがセットされると、行を印刷する基本的なアクションが実行されます。

awk "/^Entry /         { printline=0; }
     /^Entry '234238'/ { printline=1; }
     printline"

関連情報