次の形式のファイルがあるとします。
(lots of sections...)
SECTION foo
keyA=valA
...
ENDSECTION
(lots of sections...)
sedを使用してその部分を抽出できますsed -nE /^SECTION foo$/,/^ENDSECTION$/p
。私の問題は、フォーマットが次のように変更されたときに発生します。
(lots of sections...)
SECTION
keyA=valA
id=foo
...
ENDSECTION
(lots of sections...)
一般的なツール(grep、sed、awk、perl、bash)を使用してこの部分を取得する方法はありますか?
答え1
これは、文書の形式がどのように「うまく構成されているか」によって多少異なります。それぞれSECTION
に一致するものがあると確信している場合は、次のENDSECTION
コードがawk
機能します。ただし、「一行」とは呼びません(最初からこれが可能かどうかはわかりません)。
awk -v pat='id=foo' '/^SECTION/{n=f=0; delete buf;} \
{buf[++n]=$0; if (index($0,pat)) f=1} \
/^ENDSECTION/ {if (f) for (i=1;i<=n;i++) print buf[i]}' input.txt
- 検索パターンはユーザーが指定したとおりに適用されます
pat
(ただし、現在の形式では正規表現ベースの検索ではなく固定文字列検索のみを実行します)。 SECTION
(またはキーワード)で始まる行が見つかると、フラグf
(「発見」を意味)と行カウンタがn
ゼロに初期化されます。また、セクションが完了するまで印刷するかどうかを判断できないため、セクション全体をバッファリングする必要があるため、バッファ変数を消去しますbuf
。- すべての行(この例では空の行を含む)に対して行カウンタが
n
インクリメントされ、その行が配列変数に追加されますbuf
。このフラグは、行でパターンが見つかるとf
設定されます1
。 ENDSECTION
キーワードが行の先頭にあり、フラグがある場合は、バッファをf
11
行ずつ印刷してその部分を出力します。
すべての部分が空白行で区切られていることを確認できれば、この回答少ないコードでこれを行う方法の正しい方向を知ることができますが、これが保証されていないと、「ショートモード」アプローチはawk
機能しません。
また、この提案は、タスクを実行するために必要な最小限の事項です。空白行をスキップしたり、他の健全性チェック要件を満たす場合は、コードがかなり長くなる可能性があります。