Допустим, что у нас есть файл логов какого-то воркера, который выполняет некоторые работы с фруктами. Пусть его называют worker.log и содержит он следующее:
[2021-03-22 05:28:40] production.INFO: START work-21 find 500 fruits [2021-03-22 05:28:40] production.INFO: START work-22 find 400 fruits [2021-03-22 05:28:40] production.INFO: START work-23 find 300 fruits [2021-03-22 05:28:40] production.INFO: START work-24 find 200 fruits [2021-03-22 05:28:40] production.INFO: START work-25 find 20 fruits [2021-03-22 05:28:40] production.INFO: START work-21 find 50 fruits [2021-03-22 05:28:40] production.ERROR: Error message [2021-03-22 05:28:40] production.INFO: START work-22 find 17 fruits [2021-03-22 05:28:40] production.INFO: START work-23 find 58 fruits [2021-03-22 05:28:40] production.INFO: START work-21 find 500 fruits [2021-03-22 05:28:40] production.INFO: START work-22 find 400 fruits [2021-03-22 05:28:40] production.WORNING: Worning message [2021-03-22 05:28:40] production.INFO: START work-23 find 300 fruits [2021-03-22 05:28:40] production.INFO: START work-24 find 200 fruits [2021-03-22 05:28:40] production.INFO: START work-25 find 20 fruits [2021-03-22 05:28:40] production.INFO: START work-21 find 50 fruits [2021-03-22 05:28:40] production.INFO: START work-22 find 17 fruits [2021-03-22 05:28:40] production.INFO: START work-23 find 58 fruits [2021-03-22 05:28:40] production.WORNING: Worning message [2021-03-22 05:28:40] production.WORNING: Worning message [2021-03-22 05:28:40] production.INFO: START work-21 find 500 fruits [2021-03-22 05:28:40] production.INFO: START work-22 find 400 fruits [2021-03-22 05:28:40] production.INFO: START work-23 find 300 fruits [2021-03-22 05:28:40] production.INFO: START work-24 find 200 fruits [2021-03-22 05:28:40] production.ERROR: Error message [2021-03-22 05:28:40] production.INFO: START work-25 find 20 fruits [2021-03-22 05:28:40] production.INFO: START work-21 find 50 fruits [2021-03-22 05:28:40] production.ERROR: Error message [2021-03-22 05:28:40] production.INFO: START work-22 find 17 fruits [2021-03-22 05:28:40] production.INFO: START work-23 find 58 fruits
Начнём с простого.
Оставить только нужные строки лога
Если нужны только строки, которые содержат `work-22`
grep "work-22" worker.log
Получим это
Отформатировать вывод
Если надо оставить только название воркера и количество найденных фруктов
grep "START work-" worker.log | awk '{printf("%s\t%s\n", $5, $7)}'
И получим вот такой вывод
awk разбивает строку на слова. $5 и $7 значит, что нужно взять 5е и 7е слово из каждой входной строки.
Вертикальная черта говорит, что все строки, которые будут возвращены grep’ом надо передать в awk
Суммирование в найденных строках
А теперь нам надо не только отфильтровать, но и посчитать сумму найденных фруктов в каждом воркере.
grep "START work-" worker.log | awk '{ arr[$5]+=$7 } END { for (key in arr) printf("%s = %s\n", key, arr[key]) }'
Сортировка просуммированных строк
Но если воркеров дофига, то хотелось бы как-то отсортировать всё это дело, чтобы найти подебиделя. И это тоже можно
grep "START work-" worker.log \ | awk '{ arr[$5]+=$7 } END { for (key in arr) printf("%s = %s\n", key, arr[key]) }' \ | sort -n -k3
Обрати внимание на формат сложения, в массив по ключу [слово 5] нужно прибавить значение [слово 7]
Ключ -n у сортировки говорит, что надо сортировать значения как числа, -k3 говорит, что по третьему слову нужна сортировка. Слова определяются пробелами. Да, сорт работает уже с финальный строкой, а не с исходной. Если убрать символ равенства, то будет -k2.
Замечания
awk делит строку по пробелам, но используя ключ -F можно указать произвольный символ или группу символов.