Как отсортировать вывод из нескольких файлов журнала по дате - PullRequest
3 голосов
/ 21 июля 2010

Я получил вывод из нескольких разных файлов журнала:

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

Martin

Ответы [ 5 ]

2 голосов
/ 22 июля 2010

Вы можете получить удовлетворительные результаты из этого (при условии, что ни одно из ваших имен файлов не содержит двоеточий):

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 голос
/ 21 июля 2010

Если у вас уже есть вывод в файл (или вывод скрипта), я бы пошел 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 голосов
/ 22 июля 2010

Спасибо всем.

Я улучшил скрипт от Денниса Уильямсона для сортировки ошибок по дате. Каждый файл журнала с ошибкой внутри сохраняется в файле с именем отметки времени последней возникшей ошибки. Эти файлы позже сортируются и собираются вместе. Для этого могут быть более чистые решения, чем использование временных файлов.

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 голосов
/ 22 июля 2010
$ 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
0 голосов
/ 21 июля 2010
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$ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...