Я часто нахожу себя вычисляя проценты вручную после фильтрации через файл журнала, чтобы найти долю X или Y в нем. Может ли это быть легко достигнуто с помощью обычных инструментов CLI?

1 ответ1

3

Как правило, я идентифицирую несколько признаков в файле журнала, по которым я хочу различить, и получаю проценты. Это может быть легко сделано с помощью 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 к нему.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .