使用GREP获取模式的最后一个实例

时间:2017-05-23 11:37:17

标签: bash grep

我有一个文件file.log,格式如下:

23/05 04:15:10,072  [INFO ] test    Start Batch Calculation Com 
23/05 08:22:27,862  [INFO ] test    End Batch Calculation Com 
27/07 01:15:10,072  [INFO ] test    Start Batch Calculation Com 
27/07 06:22:27,862  [INFO ] test    End Batch Calculation Com 
27/07 06:22:36,192  [INFO ] test    Start Batch Fact 
27/07 06:22:36,896  [INFO ] test    End Batch Fact 
27/07 06:22:43,607  [INFO ] test    Start Batch Edition
27/07 06:22:44,888  [INFO ] test    End Batch Edition
23/05 01:15:10,072  [INFO ] test    Start Batch Calculation Com 
23/05 06:22:27,862  [INFO ] test    End Batch Calculation Com 
23/05 06:22:36,192  [INFO ] test    Start Batch Fact 
23/05 06:22:36,896  [INFO ] test    End Batch Fact 
23/05 06:22:43,607  [INFO ] test    Start Batch Edition
23/05 06:22:44,888  [INFO ] test    End Batch Edition 

我正在编写一个ksh脚本来获取包含23/05的字符串End Batch Calculation Com的时间。 23/05是实际日期。 以下是我的代码:

TimeCom=$(grep 'End Batch Calculation Com' file.log |grep "^$(date +'%d/%m')")
TimeEnd=`expr substr "$TimeCom" 7 8`
echo "$TimeEnd"

但是,这是返回23/05的第1次实例的时间....结束批量计算Com:08:22:27

我想要的是获得23/05的最后一个实例的时间....结束批量计算Com:06:22:27

知道怎么做吗?

我尝试使用tac,但这不起作用:

TimeCom=$(tac file.log | grep 'End Batch Calculation Com' file.log |grep "^$(date +'%d/%m')")

4 个答案:

答案 0 :(得分:1)

使用tail -n1管道传输单个 grep (以获取最后一个匹配的行):

d=$(date +%d/%m)
grep "^$d .* End Batch Calculation Com" file | tail -n1

输出:

23/05 06:22:27,862  [INFO ] test    End Batch Calculation Com

答案 1 :(得分:1)

TimeCom=$(grep "^$(date +'%d/%m').*End Batch Calculation Com" file.log | sort -nr | head -n1 )
TimeEnd=`expr substr "$TimeCom" 7 8`
echo "$TimeEnd"

所以,我添加了数字反向排序,所以最新时间是在第一行。

编辑:编辑后,排序是不必要的,您可以像其他答案一样使用tail -n 1,si

TimeCom=$(grep "^$(date +'%d/%m').*End Batch Calculation Com" file.log | tail -n 1 )
TimeEnd=`expr substr "$TimeCom" 7 8`
echo "$TimeEnd"

答案 2 :(得分:0)

最简单的方法是将输出传递给tail -n 1。但是,如果您有一个大文件,使用tacgrep -m 1来反转行以获得第一个匹配(即原始文件中的最后一个匹配)应该更有效。

如果您的输入在行的开头有ISO时间戳,您只需将其通过sort进行管道排序即可。实际上,您首先必须交换月份和日期(并且绝不使用文件中除ISO日期之外的任何内容):

sed -e 's#\([0-9]*\)/\([0-9]*\)#\2/\1#'

答案 3 :(得分:0)

尝试:

grep 'End Batch Calculation Com' Input_file |grep "^$(date +'%d/%m')" | tail -1

解释是我只是添加了尾部-1来获得最后一次。

修改 这也是awk的解决方案。

awk -v DATE=$(date +'%d/%m') '/End Batch Calculation Com/ && $0 ~ DATE{VAL=$0} END{print VAL}'   Input_file

所以在这里搜索字符串" ENd批量计算Com /然后将第一个字段带到名为VAL的变量,然后在awk的END部分打印它,这样它将始终打印最后一次出现的匹配值。您可以使用VAL = $(....)

将其放入变量中