如何按日期排序来自多个日志文件的输出

我有几个不同日志文件的周末:


logfile3
2010/07/21 15:28:52 INFO xxx
2010/07/21 15:31:25 INFO xxx
2010/07/21 15:31:25 DEBUG xxx

logfile1
2010/07/21 19:28:52 INFO xxx
2010/07/21 19:31:25 INFO xxx
2010/07/21 19:31:25 DEBUG xxx

logfile2
2010/07/21 13:28:52 INFO xxx
2010/07/21 13:31:25 INFO xxx
2010/07/21 13:31:25 DEBUG xxx


我想按日期对此输出进行排序,但在日志字符串上保存日志文件名,以便它应该如下所示:


logfile2
2010/07/21 13:28:52 INFO xxx
2010/07/21 13:31:25 INFO xxx
2010/07/21 13:31:25 DEBUG xxx

logfile3
2010/07/21 15:28:52 INFO xxx
2010/07/21 15:31:25 INFO xxx
2010/07/21 15:31:25 DEBUG xxx

logfile1
2010/07/21 19:28:52 INFO xxx
2010/07/21 19:31:25 INFO xxx
2010/07/21 19:31:25 DEBUG xxx


您有任何想法如何使用命令以这种方式对输出进行排序 bash, sed 或者 awk?
非常感谢!

UPDATE:
这是输出的来源


for i in $/ find log/ -iname *debug*.log -size +0 /;do
if [ `grep -c 'ERROR' $i` -gt 0 ];then
echo -e "\n$i"
grep 'ERROR' --color=auto -A 5 -B 5 $i
fi
done


马丁
已邀请:

詹大官人

赞同来自:

您可以从中获得满意的结果。 /直到您的文件名都不包含冒号/:


grep -C 5 --recursive 'ERROR' log/* | sort --field-separator=: --key=2


每个字符串都将在文件名之前。 您的输出将看起来像这样:


logfile2:2010/07/21 13:28:52 INFO xxx
logfile2:2010/07/21 13:31:25 INFO xxx
logfile2:2010/07/21 13:31:25 DEBUG xxx

logfile3:2010/07/21 15:28:52 INFO xxx
logfile3:2010/07/21 15:31:25 INFO xxx
logfile3:2010/07/21 15:31:25 DEBUG xxx
etc.


您可以使用 AWK, 要将其重新格式化为您在榜样中显示的格式:


grep -C 5 --recursive 'ERROR' log/* | sort --field-separator=: --key=2 |
awk '{colon = match/$0,":"/; file = substr/$0,1,colon - 1/;
if /file != prevfile/ {print "\n" file; prevfile = file};
print substr/$0,colon+1/}'


以下是您的脚本的一些改进,如果仍然使用它:


find log/ -iname "*debug*.log" -size +0 | while read -r file
do
if grep -qsm 1 'ERROR' "$file"
then
echo -e "\n$file"
grep 'ERROR' --color=auto -C 5 "$file"
fi
done

喜特乐

赞同来自:

如果您已在文件中已输出 /或脚本输出/ 我会去 Perl:


$/=undef;
$t=<>;
@t=split//\s*\n*/logfile.*/$/m,$t/;
foreach $f /@t/ {
next unless $f;
if/$f =~ /^logfile// {
print $f;
} else {
print join/"\n",sort /split//\n/,$f/// . "\n\n";
}
}


或许有点清洁:


@lines = //;
while/$t=<>/ {
if/$t!~ /^2\d\d\d// {
print sort @lines if/scalar/@lines//;
@lines = //;
print $t;
}
else {
push @lines,$t;
}
}
print sort @lines if/scalar/@lines//;

奔跑吧少年

赞同来自:

Nicholas-Knights-MacBook-Pro:~/logtest$ ls
logfile1 logfile2 logfile3
Nicholas-Knights-MacBook-Pro:~/logtest$ cat logfile*
2010/07/21 19:28:52 INFO xxx
2010/07/21 19:31:25 INFO xxx
2010/07/21 19:31:25 DEBUG xxx

2010/07/21 13:28:52 INFO xxx
2010/07/21 13:31:25 INFO xxx
2010/07/21 13:31:25 DEBUG xxx

2010/07/21 15:28:52 INFO xxx
2010/07/21 15:31:25 INFO xxx
2010/07/21 15:31:25 DEBUG xxx

Nicholas-Knights-MacBook-Pro:~/logtest$ for i in `ls logfile*` ; do printf "$i"; sort -n $i; printf '\n'; done
logfile1
2010/07/21 19:28:52 INFO xxx
2010/07/21 19:31:25 DEBUG xxx
2010/07/21 19:31:25 INFO xxx

logfile2
2010/07/21 13:28:52 INFO xxx
2010/07/21 13:31:25 DEBUG xxx
2010/07/21 13:31:25 INFO xxx

logfile3
2010/07/21 15:28:52 INFO xxx
2010/07/21 15:31:25 DEBUG xxx
2010/07/21 15:31:25 INFO xxx

Nicholas-Knights-MacBook-Pro:~/logtest$

君笑尘

赞同来自:

$ awk 'FNR==1{$NF=$NF" "FILENAME;}1' logfile*|sort -t" " -k1 -k2|awk 'NF==5{ h=$NF;$NF="";$0=h"\n"$0 }1'
logfile2
2010/07/21 13:28:52 INFO xxx
2010/07/21 13:31:25 DEBUG xxx
2010/07/21 13:31:25 INFO xxx
logfile3
2010/07/21 15:28:52 INFO xxx
2010/07/21 15:31:25 DEBUG xxx
2010/07/21 15:31:25 INFO xxx
logfile1
2010/07/21 19:28:52 INFO xxx
2010/07/21 19:31:25 DEBUG xxx
2010/07/21 19:31:25 INFO xxx

风见雨下

赞同来自:

谢谢大家。

我从Dennis Williamson改进了脚本,按日期排序错误。 每个具有错误中的日志文件都保存在命名的文件中 timestamp 最后一个错误出现了。 这些文件稍后被排序并一起收集。 为此,可能会有清洁的解决方案而不是使用临时文件。


find log/ -iname "*debug*.log" -size +0 | while read -r file
do
if grep -qsm 1 'ERROR' "$file"
then
echo -e "$i \t$file"
errors=$/grep 'ERROR' --color=auto -C 5 "$file"/
#get the timestamp of last error occured
time=$/echo $errors | head -n 1 | awk '{print $1" "$2}'/
timestamp=$/date -d "$time" +%s/
#save it to temp file
echo -e "\n$file\n$errors" > tmp/logs/$timestamp.$i
fi
let i++
done

#put files together
rm -f output.txt
for i in `ls tmp/logs/*|sort`;do cat $i >> output.txt ; rm $i; done


欢迎意见和改进的建议!

要回复问题请先登录注册