将匹配的行匹配到一个文件并将匹配的字符串匹配到另一个文件

时间:2017-02-23 07:21:33

标签: bash grep

我想在日志文件中搜索带有时间戳的行(并非所有行都有时间戳),我也想保留这些时间戳,以便我可以看到时间跨度,活动日期号等。

201 3083560 2013-10-21T13:57:55.334+0200    time|bootup
202 3083560 2013-10-21T13:57:55.334+0200    startup
204 3083579 2013-10-21T13:57:55.353+0200    system|device
205 3083579 2013-10-21T13:57:55.353+0200    system|manufacturer
206 3083579 2013-10-21T13:57:55.353+0200    system|model

我可以运行命令:

grep -P  '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\t' usr.log > file1.txt
grep -Po '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\t' usr.log > file2.txt

我的问题是,我可以只运行一次grep来获得我需要的一些管道吗?模式保持不变所以我想grep曾经可以节省一些时间,因为我有30k个人用户日志文件。

*将标签保留在模式的末尾非常有用,因为在某些行中,最后一列中有时间值,因此我需要排除\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\n

*我的环境是CentOS 7,grep(GNU)2.20。

非常感谢!

2 个答案:

答案 0 :(得分:0)

我不认为这可以由一个grep来完成,但如果你将一个grep的输出发送给你,你可以一次读取文件并重用grep的输出。另一个:

regex='\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\t' 
grep -P "$regex" usr.log | tee file1.txt | grep -Po "$regex" > file2.txt

tee file将输入保存到文件中,并打印到stdout,这样可以将输出保存在管道中间。

如果您可以使用awk,那么您可以利用它作为第三个字段,并在一次运行中执行此操作:

awk '/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}.[0-9]{4}\t/ \
  {print $3 > "file2.txt"; print}' usr.log > file1.txt

答案 1 :(得分:0)

如果你在perl中运行正则表达式,你可以使用$&变量在stdout和stderr之间拆分输出,只打印匹配的字符串:

perl -ne 'if(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}/){print; print STDERR "$&\n"}' usr.log > file1.txt 2> file2.txt