Я часто нахожу себя вычисляя проценты вручную после фильтрации через файл журнала, чтобы найти долю X или Y в нем. Может ли это быть легко достигнуто с помощью обычных инструментов CLI?
1 ответ
Как правило, я идентифицирую несколько признаков в файле журнала, по которым я хочу различить, и получаю проценты. Это может быть легко сделано с помощью sed, заменяя все, что вам не нужно, в каждой строке, а затем подсчитывая количество каждой из них. Например, чтобы различить попадания Linux и Windows в файл журнала, вы можете сделать:
$ cat some.log | sed -r 's/.*(Windows|Linux).*/\1/' | sort | uniq -c | sort -rn
23940 Windows
12390 Linux
Это дает вам абсолютное количество для каждой искомой черты, но не процент, так что это еще не идеально.
Кажется, что awk не может легко зацикливаться дважды по строкам, чтобы сначала вычислить общее количество, а затем вывести проценты, но с небольшим хаком мы можем сначала добавить строку сверху, которая показывает сумму всех совпадающих черт:
$ ... | awk '{s+=$1;lines=lines"\n"$0} END {printf "%d Total",s;print lines}'
Total 36330
Windows 23940
Linux 12390
Наконец, теперь, когда у нас есть общее количество, мы можем легко вычислить и напечатать проценты, используя это:
$ ... | awk '!max{max=$1}{s=$1/max*100;c=$1;$1="";printf "%30s %10d %7.2f%%\n",$0,c,s;}'
Total 36330 100.00%
Windows 23940 65.90%
Linux 12390 34.10%
Комбинированная однострочник будет тогда:
cat some.log | sed -r 's/.*(Windows|Linux).*/\1/' | sort | uniq -c | sort -rn | awk '{s+=$1;lines=lines"\n"$0} END {printf "%d Total",s;print lines}' | awk '!max{max=$1}{s=$1/max*100;c=$1;$1="";printf "%30s %10d %7.2f%%\n",$0,c,s;}'
Где some.log
- это файл, который вы хотите проверить, а Windows|Linux
- это список терминов, разделенных символом «труба» , с которыми нужно сопоставлять / различать.
Если вы хотите удалить строку Total в конце, так как она становится немного неактуальной, вы можете добавить | tail -n +2
к нему.