
次のようなテキストファイルがあります。
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.