我从几个不同的日志文件中获得了输出:
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对输出进行排序? 非常感谢!
更新: 这是输出的来源
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
马丁
答案 0 :(得分:2)
您可以从中获得满意的结果(只要您的文件名不包含冒号):
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
答案 1 :(得分:1)
如果你已经在文件(或脚本输出)中输出了,我会去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));
答案 2 :(得分:0)
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$
答案 3 :(得分:0)
$ 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
答案 4 :(得分:0)
谢谢大家。
我改进了Dennis Williamson的脚本,按日期排序错误。其中包含错误的每个日志文件都保存在由上次发生的错误的时间戳命名的文件中。稍后将这些文件排序并放在一起。可能有更清晰的解决方案,而不是使用临时文件。
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
意见和改进建议赞赏!