我有一个应用程序,它将一组日志文件输出到中央目录,如下所示:
/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 个输出行。
关于如何实现这一目标有什么建议吗?
答案1
看一下ENDFILE
块(GNUawk
特定的)。你可以按照以下方式运行一些东西
awk 'BEGINFILE { a = ""}
/prop1/ { a=$NF $2 $1} ## Change this if necessary
ENDFILE { if (a != "") print FILENAME, a}' ./node*.log
答案2
您可以按GNU's grep & sed
如下方式执行此操作:
grep -zoPhr '(.*\n)+\Kprop1=[^\n]*' /tmp/experiment/log/ | sed 's/\(.*\),\s\(.*\)/\2, \1/'
解释:
-z
选项使将grep
文件视为一个长字符串,以\0
.-r
选项将grep
递归-P
选项打开Perl
正则表达式风格。-o
选项将选择匹配的部分。-h
选项将禁止打印文件名。