私も同様の問題があるようです。これしかし、不明確性のために閉鎖されたことが確認され、新しい質問を作成します。
複数の詳細を含む1行エントリを含むログファイルがあります。
たとえば、
Mon Jan 22 12:12:12 2012 foo=blah foo2=blah2 foo3=Some longer sentence that can contain spaces and numbers somethingelse=blarg foo5=abcdefg
Mon Jan 22 12:13:12 2012 foo=blah foo2=blah3 foo3=another long sentence that could be the same or different that the prior log entry somethingelse=blarg foo5=112345abcdefg
Mon Jan 22 12:14:12 2012 foo=blah foo2=blah2 foo3=Foo923847923874Some longer sentence that can contain spaces and numbers somethingelse=blarg foo5=abcdefg
Mon Jan 22 12:15:12 2012 foo=blah foo2=blah2 foo3=Fooo02394802398402384Some longer sentence that can contain spaces and numbers somethingelse=blarg foo5=abcdefg
foo3のコンテンツ値を抽出したいです。つまり、foo3=
以降はみんな見たいのですが、以前はみんな見たいです。somethingelse=
私は似たようなことができると思いましたが、正規表現があまりにも貪欲で、grep -oP 'foo3=[\s\S]*somethingelse='
「中断(コアダンプ)エラーが発生しました。これを行うより効率的な方法はありますか?」
その他の注意:
- ログファイルは40,000行を超えるほど大容量です。
答え1
foo3
一人だけ並んでいると
sed -n '/foo3=/{s/.*foo3=//;s/\S*=.*//;p}' file.txt
-n
(オプション)でプッシュされた行を除くすべての行の印刷を無効にしますp
。以下を含む行の場合foo3=
:
foo3=
以前に含まれていたすべての項目(.*foo3=
)を何もない項目(//
)に置き換えます。*
空白ではなく、some()記号で\S
始まるすべての項目を削除します=
。- 2回の置換()後に残りを印刷します
p
。
その他
sed -n 's/.*foo3=\([^=]*\)\s\+\S*=.*/\1/p' file.txt
行全体を()の前後の一部()、空白以外の部分を除くすべての記号を含む括弧()内のパターン\1
()で置き換え、対応する代替文字のみを使用して行の残りの部分を印刷します。\(...\)
=
foo3=
*
\s
=
答え2
sed '/^foo3=/P;/\n/!s/[^ ]\{1,\}=/\n&/g;D' <infile >outfile
上記の代わりにリテラル改行文字を使用する必要があるかもしれませんが、これはn
foo3とfoo4の間にある内容だけを印刷します。
より迅速な処理のために明示的に明記してください。
sed '/\n/s/ [^ ]*=.*//p;/\n/!s/foo3=/\n\n&/;D' | grep .
または、追加のgrep
トップを使用する方が高速です。
sed 's/[^ ]\{1,\}=/\n&/g' | grep '^foo3='
答え3
この試み:
$ grep -Po "(?<=foo3\=).*(?=\s*foo4)" file.txt