替换另一个感兴趣模式之前的行中的模式

替换另一个感兴趣模式之前的行中的模式

我有一个日志文件,其中包含许多语句实例,如下所示:

14 Aug 19 16:30:11.506: <DATA>  |POS|IDLE|1|01131844090|5950|$hostIp|$size  |$data
20 Aug 19 16:30:12.439: <DATA>  |POS|IDLE|1|01131844090|5950|$hostIp|$size  |$data
21 ###############################################################################

我想替换掉IDLE前面#########..说的,END还有其他的情况IDLE保留。

我该如何实现它?

编辑:也许与我的实际文件有所不同。这个问题的答案没有达到要求。详细摘录和我的要求如下所示:

  22 Aug 19 16:47:33.159: <DATA>  |POS|RINGING|1|1126710938|5950|$hostIp|$size  |$data
    23 Aug 19 16:47:33.453: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
    24 Aug 19 16:47:33.484: <DATA>  |POS|TRAINING|1|1126710938|5950|$hostIp|$size  |$data
    25 Aug 19 16:48:05.824: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
    26 Aug 19 16:48:05.916: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
    27 Aug 19 16:48:05.947: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
    28 Aug 19 16:48:23.792: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
    29 Aug 19 16:48:23.853: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
    30 Aug 19 16:48:23.884: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
    31 ##############################################################################

对上面的实例进行操作后,结果应该是:(IDLE####一行更改为END。注意此类事件的实例有很多。我的实际需要是找到RINGING和之间的时间差IDLE - aka END)

22 Aug 19 16:47:33.159: <DATA>  |POS|RINGING|1|1126710938|5950|$hostIp|$size  |$data
23 Aug 19 16:47:33.453: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
24 Aug 19 16:47:33.484: <DATA>  |POS|TRAINING|1|1126710938|5950|$hostIp|$size  |$data
25 Aug 19 16:48:05.824: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
26 Aug 19 16:48:05.916: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
27 Aug 19 16:48:05.947: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
28 Aug 19 16:48:23.792: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
29 Aug 19 16:48:23.853: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
30 Aug 19 16:48:23.884: <DATA>  |POS|END|1|1126710938|5950|$hostIp|$size  |$data
31 ##############################################################################

答案1

更新ex命令方式仅对第一个匹配行有效。 perl 示例将用该模式替换所有行,但只会提供输出而不编辑原始文件,因此您必须将输出重定向到新文件。 YOUR-LOGFILE 应替换为您尝试修改的文件的位置。

perl -0pe 's/IDLE(.*\n.*###)/END\1/g' 您的日志文件 > 新文件

这将替换包含模式的行上方的行,然后退出。

ex -s +'/######/-1 s/空闲/结束/ | x' 您的日志文件

答案2

尝试:

$ awk '!/^#+$/ {print l; l=$0; next} {gsub("IDLE","END",l); print l; l=$0} END {print $0}' < log.txt

这使:

Aug 19 16:30:11.506: <DATA>  |POS|IDLE|1|01131844090|5950|$hostIp|$size  |$data
Aug 19 16:30:12.439: <DATA>  |POS|END|1|01131844090|5950|$hostIp|$size  |$data
###############################################################################

答案3

sed '$!N;/###$/s/IDLE/END/;P;D
' <<\DATA
22 Aug 19 16:47:33.159: <DATA>  |POS|RINGING|1|1126710938|5950|$hostIp|$size  |$data
23 Aug 19 16:47:33.453: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
24 Aug 19 16:47:33.484: <DATA>  |POS|TRAINING|1|1126710938|5950|$hostIp|$size  |$data
25 Aug 19 16:48:05.824: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
26 Aug 19 16:48:05.916: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
27 Aug 19 16:48:05.947: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
28 Aug 19 16:48:23.792: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
29 Aug 19 16:48:23.853: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
30 Aug 19 16:48:23.884: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
31 ##############################################################################
DATA

sed这将 的正常一行缓冲区扩展为两行缓冲区。在除最后一行之外的每一行上,它将下一个输入行附加到模式空间。如果两行缓冲区以字符串结尾, ###它将用 替换第一个出现的IDLE字符串END。然后,它P会打印到缓冲区中第一个出现的换行符,并D删除相同的换行符,然后再重新开始剩余的内容。对于您的问题来说,这是一个极其简单、可移植且非常快速的解决方案。

输出

22 Aug 19 16:47:33.159: <DATA>  |POS|RINGING|1|1126710938|5950|$hostIp|$size  |$data
23 Aug 19 16:47:33.453: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
24 Aug 19 16:47:33.484: <DATA>  |POS|TRAINING|1|1126710938|5950|$hostIp|$size  |$data
25 Aug 19 16:48:05.824: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
26 Aug 19 16:48:05.916: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
27 Aug 19 16:48:05.947: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
28 Aug 19 16:48:23.792: <DATA>  |POS|IDLE|1|1126710938|5950|$hostIp|$size  |$data
29 Aug 19 16:48:23.853: <DATA>  |POS|INIT|1|1126710938|5950|$hostIp|$size  |$data
30 Aug 19 16:48:23.884: <DATA>  |POS|END|1|1126710938|5950|$hostIp|$size  |$data
31 ##############################################################################

要就地编辑文件,您可以执行以下操作:

 sed '$!N;/###$/s/IDLE/END/;P;D
 ' <<FILE >file
 $(cat file)
 FILE

或者,使用 GNUsed至少你可以这样做:

 sed -i '$!N;/###$/s/IDLE/END/;P;D' file

相关内容