次のような中央ディレクトリにログファイルのセットを出力するアプリケーションがあります。
/tmp/experiment/log/
├── node01.log
├── node02.log
├── node03.log
├── node04.log
├── node05.log
├── node06.log
各ファイル内では、各ログのプロセスの存続期間中にさまざまな測定が行われるため、行は次のようになります。
prop1=5, ts=X, node01
prop2=3, ts=X, node01
prop1=7, ts=Y, node01
...
すべてのファイルを処理し、指定されたプロパティの最後の読み取り値を出力できるコマンドを作成するのに苦労しています。理想的には、次のようなものを出力します。
node01, prop1=7, ts=...
node02, prop1=9, ts=...
node03, prop1=3, ts=...
助言がありますか? grep
、cut
、sort
、uniq
の組み合わせを次のように使い始めました。
$ grep -sirh "prop1" /tmp/experiment/log/ | \
cut --delimiter=, --fields=1,4 | uniq | sort | \
tail -n 14` --this example had 14 log files
ただし、一部の実験では同じログの複数のレコードを印刷し、他のいくつかのログを除外するため、部分的にしか機能しませんでした。
これでawk
に移動しました:
$ awk -F":" '/prop1/ { print $NF $2}' /tmp/experiment/log/node*.log | \
awk 'END { print }'
また、複数の入力ファイルを渡すと、ログファイルごとに1つの出力行ではなく、最後のログファイルの最後の行しか表示されないという問題がありました。
これを達成する方法について何か提案はありますか?
ENDFILE
ブロック(GNU awk
固有)を見てください。あなたはの線に沿って何かを実行することができます
awk 'BEGINFILE { a = ""}
/prop1/ { a=$NF $2 $1} ## Change this if necessary
ENDFILE { if (a != "") print FILENAME, a}' ./node*.log
GNU's grep & sed
を使用すると、次のようにこれを行うことができます。
grep -zoPhr '(.*\n)+\Kprop1=[^\n]*' /tmp/experiment/log/ | sed 's/\(.*\),\s\(.*\)/\2, \1/'
説明:
-z
オプションを使用すると、grep
はファイルを\0
で区切られた1つの長い文字列として扱います。-r
オプションはgrep
を再帰的にします-P
オプションは、Perl
正規表現フレーバーをオンにします。-o
オプションは、一致する部分を選択します。-h
オプションは、ファイル名の印刷を抑制します。