当前日志:
18:56:54 Info: Starting
18:56:55 Error: timed out
18:56:56 Error: timed out
18:56:57 Error: timed out
18:56:58 Info: reconnected
18:56:59 Error: timed out
期望的输出:
18:56:54 Info: Starting
18:56:55 Error: timed out (3)
18:56:57 Info: reconnected
18:56:58 Error: timed out
我的日志文件可能有数千个重复行,我想使用 bash/linux 命令复制 chrome 日志的行为。
我发现这个,很接近: 删除部分重复的连续行,但保留第一行和最后一行
它给出了这个神奇的 awk 命令:
awk '{n=$2$3$4$5$6$7}l1!=n{if(p)print l0; print; p=0}l1==n{p=1}{l0=$0; l1=n}END{print}' file
(至关重要的是,排除 n=$1 允许时间戳不同,这是必需的。显示压缩行的确切时间戳并不重要。)
但我还需要添加一个计数器,所以我清楚地知道删除了什么,在可读性和准确性之间做出了适当的妥协(唯一丢失的信息将是重复消息的确切时间,有第一个或最后一个时间戳就足够了。 )
谢谢,我不擅长 awk,刚刚了解了 uniq,希望有人可以将我链接到解决方案,或者将其视为一个有趣的练习。干杯。
答案1
不需要awk
,直接使用即可uniq
,
uniq -c -f 1 file
该-c
选项给出了在输入中连续找到一行的次数,并且您可以使用 跳过第一个空格或制表符分隔字段中的时间戳-f 1
。
给出问题中数据的示例:
$ uniq -c -f 1 file
1 18:56:54 Info: Starting
3 18:56:55 Error: timed out
1 18:56:58 Info: reconnected
1 18:56:59 Error: timed out
答案2
如果您对行开头的计数感到满意,uniq
那么您所需要的就是:
$ uniq -f 1 -c log.txt
1 18:56:54 Info: Starting
3 18:56:55 Error: timed out
1 18:56:58 Info: reconnected
1 18:56:59 Error: timed outhet
-f 1
跳过第一个字段,-c
计算行数。
要获得您要求的确切格式,您需要处理uniq
的输出,例如sed
:
$ uniq -f1 -c log.txt |
sed -E -e 's/^[[:space:]]+//;
s/^([[:digit:]]+)[[:space:]]+(.*)/\2 (\1)/;
s/ \(1\)$//'
18:56:54 Info: Starting
18:56:55 Error: timed out (3)
18:56:58 Info: reconnected
18:56:59 Error: timed out
sed 脚本使用扩展正则表达式(-E
选项)又名 ERE,而不是默认的基本正则表达式 (BRE) 并且:
- 去除每行的前导空格
- 将每行开头的所有数字移动到行尾,用括号括起来
- 从每行末尾删除“(1)”(如果存在)。
答案3
使用 awk实用程序我们可以得出事件的唯一计数,如下所示:
$ awk '
{t=substr($0,1+index($0,FS))}
prev != t {
if (NR>1) {fx(line,knt)}
knt = 0
prev = t
}{
line = $0
knt++
}
END {fx(line,knt)}
function fx(a,b) {
print a (b>1?sprintf("%s(%d)",OFS,b):"")
}
' file
18:56:54 Info: Starting
18:56:57 Error: timed out (3)
18:56:58 Info: reconnected
18:56:59 Error: timed out
笔记:-
- 假设没有前导空格/没有连续空格。
答案4
命令
uniq -f 1 -c filename| awk '{print $2,$3,$4,$5,$1}'| awk '{if($NF > 1){$NF="("$NF")";print }else{$NF="";print }}'
输出
18:56:54 Info: Starting
18:56:55 Error: timed out (3)
18:56:58 Info: reconnected
18:56:59 Error: timed out