grep -c ERROR app.log считает строки, в которых встретилось слово; grep -o ERROR app.log | wc -l считает, сколько раз слово встретилось на самом деле. На одном и том же файле это 3 и 4, а разница — единственная строка с двумя ошибками. Какое число нужно вам, зависит от вопроса, который вы имели в виду.
1. Сколько строк содержит слово
$ clai сколько строк в app.log содержат ERROR→ grep -c ERROR app.log3
-c считает строки с совпадением, а не совпадения. Строка, где ERROR встретился дважды, всё равно считается за одну.
2. Сколько раз встречается слово
$ clai сколько раз встречается ERROR в app.log→ grep -o ERROR app.log | wc -l4
3 против 4 на том же самом файле. -o печатает каждое совпадение отдельной строкой, и только после этого wc -l считает вхождения. Лишнее — та самая строка с двумя ошибками.
3. Без учёта регистра
$ clai посчитай строки с error в любом регистре→ grep -ic error app.log4
-i подобрал четвёртую строку — ту, где слово написано строчными. В логе, куда пишут несколько сервисов, регистр никто не гарантирует.
4. Топ сообщений об ошибках
$ clai покажи, какие ошибки встречаются чаще всего→ grep -o 'ERROR [a-z ]*' app.log | sed 's/ *$//' | sort | uniq -c | sort -rn 2 ERROR timeout connecting to db 1 ERROR retry failed 1 ERROR permission denied
Обычно ради этого всё и затевается. -o вытаскивает текст ошибки, sed убирает хвостовые пробелы, uniq -c считает, а второй sort -rn поднимает частые наверх.
5. Распределение по часам
$ clai покажи, в какие часы были ошибки→ grep ERROR app.log | cut -c12-13 | sort | uniq -c 1 09 1 10 1 11
cut -c12-13 вырезает час из отметки времени вида 2026-08-10 09:12:03. Позиции зависят от формата вашего лога — посмотрите на одну строку и пересчитайте символы, прежде чем копировать.
6. Сразу по нескольким файлам
$ clai посчитай ошибки в каждом файле логов→ grep -c ERROR *.logapp.log:3app2.log:3
Когда файлов больше одного, grep печатает имя и счётчик через двоеточие. Чтобы отранжировать: grep -c ERROR *.log | sort -t: -k2 -rn.
Gotchas
grep -cне считает вхождения. Проверено на одном файле:-cговорит 3,-o | wc -lговорит 4. Если строка совпала дважды,-cэтого не видит. Решите, какой вопрос вы задаёте: «сколько строк» или «сколько раз».grep -oбез совпадений печатает пустоту и выходит с кодом 1. В конвейере сwc -lэто выглядит как честный ноль, но статус ненулевой, и скрипт сset -eумрёт ровно здесь.- Позиции в
cut -cпривязаны к формату лога. Стоит логгеру добавить миллисекунды или имя хоста в начало строки, и разбивка по часам молча посчитает не те символы. Для нестабильных форматов берите поля:awk '{print $2}'.
Related questions
Как считать слова целиком, а не подстроки? grep -wo error — -w требует границ слова, иначе в счёт попадут errors и errorlog.
Как считать в сжатых логах? zgrep -c ERROR app.log.1.gz работает как grep и не распаковывает файл на диск.
Как посчитать разные значения? Добавьте sort -u перед подсчётом: grep -o 'ERROR [a-z ]*' app.log | sort -u | wc -l покажет число различных сообщений, а не их общее количество.
See also
- Следить сразу за несколькими логами
- journalctl: логи одного сервиса
- Убрать повторяющиеся строки — с сортировкой и без
CliAI превращает «сколько раз» и «сколько строк» в две разные команды и показывает, какую именно выбрал. Поставить одной строкой.