在grep之后回复每行之前的文本并在Unix上剪切

时间:2015-06-18 04:01:35

标签: bash shell unix scripting

我正在尝试在Unix上使多个日志文件的作业输出更加用户友好。

日志文件从最新的Web.log到最早的Web.log.30。我正在从这些文件中获取job123,然后管道到一个新的grep,只有带有Exit消息的行,这意味着作业已经完成。然后我在逗号上剪切它,这样我只打印出时间戳而不是整行。这是我的剧本:

for file in `ls -tr Web.log*`; do grep job123 $file | grep Exit | cut -d "," -f1; done

按时间顺序输出我想要的时间戳:

2015-06-17 21:07:00
2015-06-17 22:07:00
2015-06-17 23:07:00
2015-06-18 00:07:00
2015-06-18 01:07:00
2015-06-18 02:07:00
2015-06-18 03:07:00

我想要做的就是在每行的开头添加一个echo,说“Script job123 ran at:”所以它看起来像这样:

Script job123 ran at: 2015-06-17 21:07:00
Script job123 ran at: 2015-06-17 22:07:00
Script job123 ran at: 2015-06-17 23:07:00
Script job123 ran at: 2015-06-18 00:07:00
Script job123 ran at: 2015-06-18 01:07:00
Script job123 ran at: 2015-06-18 02:07:00
Script job123 ran at: 2015-06-18 03:07:00

由于用户几乎不了解Unix,我只需要尽可能方便用户阅读。我正在与回声部分挣扎。

此外,每个日志文件的长度大约为25MB,因此系列管道可能会耗费内存,因此如果有人对加快速度有任何建议,我们非常感激。

请注意,这是在生产服务器上,因此安装其他脚本(如multigrep)是不可能的。我想把它作为单行脚本来实现,以使用户更加简单。

任何方式我都可以回复我目前使用的脚本上的文字?我已经试过在几个阶段回应它,但没有运气。

谢谢。

2 个答案:

答案 0 :(得分:1)

将命令的输出存储在变量中,并使用其他文本进行打印:

for file in `ls -tr Web.log*`; do 
  out=$(grep job123 $file | grep Exit | cut -d "," -f1;)
  echo "Script job123 ran at: ${out}"
done

您还可以将两个grep合并为一个:

out=$(grep -E 'job123.*Exit|Exit.*job123' $file)

如果您可以使用awk,那么它可以简化为单个命令:

out=$(awk -F, '/job123/&&/Exit/{print $1}' $file)

由于你必须解析每一行,awk解决方案(没有管道)会更好。但我不能说你得到多少加速。

答案 1 :(得分:1)

重新使用您的代码,可以将cut命令(cut -d "," -f1)替换为awk -F, '{print "Script job123 ran at: " $1}'

来实现

另外,仅使用awk就可以实现同样的效果:

for file in `ls -tr Web.log*`; do awk -F, '/job123/&&/Exit/{print "Script job123 ran at: " $1}' $file; done