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

Bash 使用GREP获取模式的最后一个实例,bash,grep,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

我有一个文件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的字符串结束批处理计算Com的时间。23/05是实际日期。 下面是我的代码:

TimeCom=$(grep 'End Batch Calculation Com' file.log |grep "^$(date +'%d/%m')")
TimeEnd=`expr substr "$TimeCom" 7 8`
echo "$TimeEnd"
但是,这将返回05年23月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')")

最简单的方法是通过管道将输出传输到
tail-n1
。但是,如果您有一个大文件,那么使用
tac
grep-m1
反转行以获得第一个匹配(即原始文件中的最后一个匹配)应该更有效

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


最简单的方法是通过管道将输出传输到
tail-n1
。但是,如果您有一个大文件,那么使用
tac
grep-m1
反转行以获得第一个匹配(即原始文件中的最后一个匹配)应该更有效

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

尝试:

原因是我只是简单地添加了tail-1以获得最终结果

编辑: 这里还有一个awk的解决方案

awk -v DATE=$(date +'%d/%m') '/End Batch Calculation Com/ && $0 ~ DATE{VAL=$0} END{print VAL}'   Input_file
因此,在此处搜索字符串“ENd Batch Calculation Com/然后将第一个字段带到名为VAL的变量,然后在awk的ENd部分打印它,这样它将始终打印匹配值的最后一次出现。您也可以使用VAL=$(..)将其放入变量中。

尝试:

原因是我只是简单地添加了tail-1以获得最终结果

编辑: 这里还有一个awk的解决方案

awk -v DATE=$(date +'%d/%m') '/End Batch Calculation Com/ && $0 ~ DATE{VAL=$0} END{print VAL}'   Input_file
因此,在这里搜索字符串“ENd Batch Calculation Com/然后将第一个字段带到名为VAL的变量,然后在awk的ENd部分打印它,这样它将始终打印匹配值的最后一次出现。您也可以通过使用VAL=$(..)

和单grep以及
tail-n1
(获取最后匹配的行)将其放入变量中:

输出:

23/05 06:22:27,862  [INFO ] test    End Batch Calculation Com
使用单grep
tail-n1
管道连接(以获取最后匹配的行):

输出:

23/05 06:22:27,862  [INFO ] test    End Batch Calculation Com
因此,我添加了一个数字反向排序,所以最新时间在第一行

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

TimeCom=$(grep "^$(date +'%d/%m').*End Batch Calculation Com" file.log | tail -n 1 )
TimeEnd=`expr substr "$TimeCom" 7 8`
echo "$TimeEnd"
因此,我添加了一个数字反向排序,所以最新时间在第一行

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

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

在第一行结束括号之前添加
| tail-1
。您的
tac
解决方案提供了什么?使用
尾-1是什么意思?因为文件是一个连续的日志
,所以尾-1将不起作用。您想在接下来的100年中保持灰色吗?在第一行的括号结束之前添加
|尾-1
。您的
tac
解决方案为您提供了什么?使用
是什么意思?tail-1不起作用,因为文件是一个连续的日志
,您想在接下来的100年中保持grepping吗?tail-1不起作用,因为文件是一个连续的日志。我尝试在grep之前添加tac,但它不起作用。我已经编辑了我的问题。我添加了1个awk命令,现在也是解决方案,请现在也尝试一下。尾部-1将无法工作,因为该文件是一个连续的日志。我尝试在grep之前添加tac,但它不起作用。我已经编辑了我的问题。我添加了一个awk命令,现在也是解决方案。请现在也尝试一下。这不起作用。如果我在你的问题中使用日志文件,我现在得到
06:22:27
。编辑后是否尝试过?此操作无效。如果我在你的问题中使用日志文件,我现在得到
06:22:27
。编辑后你试过了吗?
TimeCom=$(grep "^$(date +'%d/%m').*End Batch Calculation Com" file.log | tail -n 1 )
TimeEnd=`expr substr "$TimeCom" 7 8`
echo "$TimeEnd"