我有一个日志文件,其中包含许多语句实例,如下所示:
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