我有一个包含这样的行的日志文件:
...timestamp...(id=1234)..GO...
...timestamp...(id=1234)..DONE...
事实:
我想要的是什么:
(理想情况下)创建一个以下格式的新文件:
diffTime <GO line> <DONE line>
我的主要观点是区分时间戳。这将非常有用,我缺乏编写它的sort / sed / awk技能。是否有日志文件工具来帮助解决这种黑客问题?
答案 0 :(得分:3)
我不知道任何这样的工具,但可以在shell中编写它。例如,此日志:
11:18:51 (id=123) GO 11:18:52 (id=124) GO 11:18:53 (id=123) DONE 11:18:54 (id=125) GO 11:18:55 (id=125) DONE 11:18:55 (id=124) DONE
可以转换为
2 123 3 124 1 125
第一列是以秒为单位的时间,第二列是事务ID。
命令是:
cat example.log
| sed 's|\([^ ]\+\) (id=\([^)]\+\)) \(.\+\)|\1 \2 \3|;s|GO|1|;s|DONE|2|'
| sort -k2,3
| paste - -
| tr ':' ' '
| awk '{printf("%d %d\n", ((($6-$1)*60*60)+(($7-$2)*60)+($8-$3)), $4)}'
这种单行程可能会更加简化。
工作原理:
awk
次尝试)答案 1 :(得分:2)
这是一个让你半途而废的脚本:
#!/bin/bash
# Script must be called with one parameter, the name of the file to process
if [ $# -ne 1 ]; then
echo "Usage: $0 filename"
exit
fi
filename=$1
# Use sed to put the timestamp after the id
# 10:46:01:0000 (id=20) GO
# 10:46:02:0000 (id=10) GO
# 10:46:03:0000 (id=10) DONE
# 10:46:04:0000 (id=20) DONE
#
# becomes
#
# (id=20) 10:46:01:0000 GO
# (id=10) 10:46:02:0000 GO
# (id=10) 10:46:03:0000 DONE
# (id=20) 10:46:04:0000 DONE
#
# \1 timestamp
# \2 id
# \3 status (GO or DONE)
# \1 \2 \3
sed -e "s/\([0-9:]*\) \((id=[0-9]*)\) \(.*\)/\2 \1 \3/" $filename > temp1
# Now sort the file. This will cause timestamps to be sorted, grouped by id
# (id=20) 10:46:01:0000 GO
# (id=10) 10:46:02:0000 GO
# (id=10) 10:46:03:0000 DONE
# (id=20) 10:46:04:0000 DONE
#
# becomes
#
# (id=10) 10:46:02:0000 GO
# (id=10) 10:46:03:0000 DONE
# (id=20) 10:46:01:0000 GO
# (id=20) 10:46:04:0000 DONE
sort temp1 > temp2
# Use sed to put the id after the timestamp
# (id=10) 10:46:02:0000 GO
# (id=10) 10:46:03:0000 DONE
# (id=20) 10:46:01:0000 GO
# (id=20) 10:46:04:0000 DONE
#
# becomes
#
# 10:46:02:0000 (id=10) GO
# 10:46:03:0000 (id=10) DONE
# 10:46:01:0000 (id=20) GO
# 10:46:04:0000 (id=20) DONE
# \1 id
# \2 timestamp
# \3 status (GO or DONE)
sed -e "s/\((id=[0-9]*)\) \([0-9:]*\) \(.*\)/\2 \1 \3/" temp2 > temp3
其余的...在运行此脚本之后,每个GO行后面都会跟一个具有相同id的DONE行,假设存在这样的DONE行。
接下来,您可以读取每对行,提取时间戳并区分它们(查看Johnsyweb建议的时间戳函数)。然后将两条线合并为一条线。您的结果现在看起来像:
# 1s 10:46:02:0000 (id=10) GO 10:46:03:0000 (id=10) DONE
# 3s 10:46:01:0000 (id=20) GO 10:46:04:0000 (id=20) DONE
注意起始时间戳的条目是如何乱序的。这是因为我们之前按id排序。我将把它作为练习让你弄清楚如何以正确的顺序获得条目。我们希望id = 20的条目在id = 10之前,因为id = 20是在id = 10之前启动的。
# 3s 10:46:01:0000 (id=20) GO 10:46:04:0000 (id=20) DONE
# 1s 10:46:02:0000 (id=10) GO 10:46:03:0000 (id=10) DONE
我确定这很令人困惑,所以如果您有疑问,请告诉我。我确信有更有效的方法可以做到这一切,但这就是我想到的。