2010-07-21 94 views
3

我有輸出:如何從多個日誌文件,按日期排序輸出從幾個不同的日誌文件

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 

源馬丁

+0

「我已經從幾個不同的日誌文件得到輸出......」在一個文件中? – leonbloy 2010-07-21 19:18:30

+0

時間重疊嗎?如果是這樣,你想如何報告文件? – deinst 2010-07-21 19:30:20

回答

0

謝謝大家。

我改進了丹尼斯威廉姆森的腳本,按日期排序錯誤。每個內部存在錯誤的日誌文件都保存在由上次發生錯誤的時間戳命名的文件中。這些文件稍後進行排序並放在一起。可能會有更清晰的解決方案,而不是使用臨時文件。

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 

意見和改進建議表示讚賞!

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$ 
+0

謝謝尼古拉斯,對不起,如果我不清楚。我想根據日誌行的日期對輸出進行排序,而不是按文件名進行排序 - 請參閱我的問題以獲取所需輸出。 – Martin 2010-07-21 19:24:18

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)); 
+0

不,它來自多個文件,我已將源腳本更新爲該問題。我怎樣才能使用這個腳本?謝謝! – Martin 2010-07-21 19:43:14

+0

它來自多個文件,但你已經有輸出合併?如果是這樣,是的,我的腳本可能會有幫助。但是在腳本中進行排序會更容易。 – leonbloy 2010-07-21 19:52:50

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 
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