Bash スクリプトのヘルプ - テキスト解析と出力

Bash スクリプトのヘルプ - テキスト解析と出力

次のようなテキストファイルがあります。

a  b   c               d
-- -- --              --
1  ok device issue   Some Action which 
                     has to be taken which 
                     is split into many lines
                     under d.

「issue」に grep を使用しようとしましたが、「d」の最初の行のみが印刷されます。出力は次のようになります。

1  ok device issue   Some Action which 

しかし、完全な出力を d にしたいのです。ファイルを csv で保存しようとすると、列 d の 2 行目が新しい行として表示されました。

編集:

出力は複数のデバイスから取得され、変数に保存され、その中から問題のあるデバイスを grep で検索します。

答え1

ここでは複数行の grep が必要です。そのためには、PCRE 対応-P オプションが必要です。grep は slurp-zモードで Null で区切られたレコードを出力するため、tr コマンドを使用してそれらを削除します。

$ < file grep -Pzo '.*\S.*issue.*\n(?:\h+.*\n)+'  | tr -d '\0'

答え2

grepデフォルトモードでは期待通りに動作しています。manページから引用します。

...grep は各 FILE で PATTERNS を検索します。PATTERNS は改行文字で区切られた 1 つ以上のパターンであり、grep はパターンに一致する各行を出力します...

だから、それは現れるはずだテキスト内の に一致する行regex。行は制御コードで区切られておりnewline、これがあなたが見ている動作を説明しています。-z応答で言及されているオプションを使用する以外に、「問題」が一致させたい正規表現であると仮定します(実際に一致させたいのが'Device Degraded'または'\sDegraded'または'\sError'である場合は に置き換えます)。また、「修正アクション」列が機械生成され、一貫している(つまり、常に 4 行にまたがる)場合は、単に を実行してgrep -A 3 '\sissue' > issues保存することもできます。興味のある行のみファイルに書き込むと、次のような出力が生成されます。

1  ok device issue  Some Action which 
                        has to be taken which 
                        is split into many lines 
                        under d.
--
10  ok device issue Some Action which
            has to be taken which 
            is split into may lines
            under d. 
--
211 ok device issue Some Action which
            has to be taken which 
            is split into many lines 
            under d.

これらのオプションの機能の詳細については、grep のマニュアル ページを参照してください。

答え3

入力ファイル内の「レコード」が OP によって提供されたとおりであると仮定します。

$ sed '/issue/!d; :a; n; /^[0-9]\{1,\} /d; $!ba' file
1  ok device issue   Some Action which 
                     has to be taken which 
                     is split into many lines
                     under d.
$

答え4

これは、あらゆる UNIX ボックス上のあらゆるシェルで awk を使用する場合に必要となる可能性があります。

$ cat tst.awk
/^[0-9]/ { prt() }
{ rec = rec $0 ORS }
END { prt() }

function prt() {
    if ( rec ~ regexp ) {
        printf "%s", rec
    }
    rec = ""
}

$ awk -v regexp='issue' -f tst.awk file
1  ok device issue   Some Action which
                     has to be taken which
                     is split into many lines
                     under d.

関連情報