Умение подсчитывать строки в файле или в выводе команды является обязательным в Linux.

Как посчитать строки в файле в Linux?

Linux предоставляет команду wc, которая позволяет подсчитывать строки, слова и байты в файле или из стандартного ввода. Это может быть очень полезно во многих случаях, вот некоторые примеры: получение количества ошибок в файле журнала или анализ вывода, полученного от других команд Linux.

Сколько ошибок вы видите в журналах вашего приложения? Сколько уникальных пользователей воспользовались вашим приложением сегодня?

Это всего лишь два примера ситуаций, в которых вам необходимо уметь подсчитывать строки файла.

Итак, как можно подсчитать количество строк в файле с помощью Linux?

Давайте узнаем как!

Команда Linux для подсчета строк

Наиболее используемая для этого команда — wc (подсчет слов).

Допустим, мы хотим подсчитать количество строк в файле /var/log/messages.

Этот файл содержит глобальные системные сообщения и очень полезен для устранения неполадок в вашей системе Linux.

Для подсчета количества строк мы будем использовать следующий синтаксис:

wc -l <filename>
wc -l /var/log/messages 
2094 /var/log/messages

Флаг -l используется для получения количества строк. Причина использования этого флага в том, что команда wc позволяет делать гораздо больше, чем просто подсчитывать строки…

Как видите, в данном случае количество строк в файле составляет 2094.

Подсчет вхождений шаблона в файл

Теперь предположим, что мы хотим подсчитать количество ошибок в одном и том же файле.

Мы можем использовать команду grep, а затем команду wc, используя канал.

Канал используется для отправки стандартного вывода команды, расположенной перед каналом, на стандартный ввод команды, расположенной после канала.

grep <patter-you-are-looking-for> <filename> | wc -l

Здесь вывод команды grep становится вводом команды wc.

Вывод команды grep без конвейера будет следующим:

grep ERROR /var/log/messages 
Aug 23 14:43:02 localhost firewalld[28104]: ERROR: Failed to load service file 'RH-Satellite-6.xml': PARSE_ERROR: Unexpected element include
Aug 23 14:43:02 localhost firewalld[28104]: ERROR: Failed to load service file 'freeipa-4.xml': PARSE_ERROR: Unexpected element include

Итак, у нас есть две строки, содержащие строку ERROR.

Если мы используем символ конвейера, а затем команду wc, то мы больше не увидим строки, а только их количество:

grep ERROR /var/log/messages | wc -l
2

Еще один пример…

Я хочу узнать, сколько раз был перезапущен веб-сервер Apache на моем компьютере Linux.

Сначала ищем все строки в /var/log/messages, содержащие слово «Apache»:

grep -i apache /var/log/messages
Aug 23 13:52:29 localhost systemd[1]: Stopping The Apache HTTP Server...
Aug 23 13:52:30 localhost systemd[1]: Stopped The Apache HTTP Server.
Aug 23 13:52:33 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 23 13:52:33 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 14:53:05 localhost systemd[1]: Stopping The Apache HTTP Server...
Aug 23 14:53:06 localhost systemd[1]: Stopped The Apache HTTP Server.
Aug 23 14:53:06 localhost systemd[1]: Starting The Apache HTTP Server...
...

Мы используем флаг -i в команде grep, чтобы игнорировать регистр при поиске совпадений, поэтому наша команда grep будет находить строки, содержащие текст «apache» или «Apache».

Мы видим, что Apache регистрирует следующее сообщение при успешном запуске:

Aug 23 13:52:33 localhost systemd[1]: Started The Apache HTTP Server.

Итак, наша команда grep становится такой:

grep -i apache /var/log/messages | grep Started
Aug 22 23:59:25 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 13:52:33 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 14:53:06 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 14:56:35 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 15:02:44 localhost systemd[1]: Started The Apache HTTP Server.
Aug 23 15:10:21 localhost systemd[1]: Started The Apache HTTP Server.

Две команды grep?

Да, вы можете использовать канал для объединения нескольких команд, даже если это одна и та же команда, как в этом случае.

И наконец, мы можем прибавить wc, чтобы получить общее количество:

grep -i apache /var/log/messages | grep Started | wc -l
13

Итак, наш Apache был успешно перезапущен 13 раз.

Тот же результат команды выше можно получить, используя флаг -c для команды grep.

Команда выше становится следующей:

grep -i apache /var/log/messages | grep -c Started

Команду wc можно также использовать для подсчета количества строк в нескольких файлах:

wc -l /var/log/messages /var/log/cron /var/log/maillog 
  2100 /var/log/messages
   183 /var/log/cron
     0 /var/log/maillog
  2283 total

Очень полезно!

Подсчет количества файлов с определенным расширением

Если мы хотим подсчитать количество файлов с расширением.log внутри каталога /var/log/, мы можем использовать:

ls -al /var/log/*.log
-rw-------. 1 root root      0 Feb 24 03:46 /var/log/boot.log
-rw-r--r--. 1 root root 454593 Feb 23 14:40 /var/log/dnf.librepo.log
-rw-r--r--. 1 root root 312448 Feb 24 17:03 /var/log/dnf.log
-rw-r--r--. 1 root root  90680 Feb 24 17:03 /var/log/dnf.rpm.log
-rw-r--r--. 1 root root  20639 Feb 24 15:03 /var/log/hawkey.log

Подстановочный знак *.log используется для сопоставления всех файлов с расширением .log.

Что делать, если мы хотим получить фактическое количество файлов?

Снова используем pipe и команду wc:

ls -al /var/log/*.log | wc -l
5

Возможности wc в сочетании с другими командами Linux безграничны!

Вывод команды wc без флагов

Давайте выполним предыдущую команду:

ls -al /var/log/*.log | wc -l

Но на этот раз без передачи каких-либо флагов команде wc.

Что происходит?

[myuser@localhost]$ ls -al /var/log/*.log | wc
      5      45     321

В выводе мы видим три числа… что они обозначают?

Это общее количество строк, слов и байтов.

Из предыдущего примера мы уже видим, что 5 — это количество строк. Давайте убедимся, что 45 и 321 — это количество слов и байтов.

Флаг -m для команды wc позволяет получить только количество слов:

[myuser@localhost]$ ls -al /var/log/*.log | wc -w
45

И флаг -c для получения количества байтов:

[myuser@localhost]$ ls -al /var/log/*.log | wc -c
321

Подсчитайте количество строк в архивном файле в Linux

До сих пор мы видели, как подсчитывать строки файлов в Linux.

Что делать, если я хочу подсчитать количество строк в сжатом файле?

Прежде всего, мы можем использовать команду zcat для печати содержимого сжатого файла.

Допустим, у нас есть заархивированный файл app_logs.gz. Чтобы просмотреть его содержимое, я могу использовать следующую команду:

zcat app_logs.gz

Чтобы увидеть количество строк в этом файле, я могу просто использовать символ конвейера, а затем команду wc, как мы видели в предыдущих разделах:

zcat app_logs.gz | wc -l

Таким образом, нет необходимости использовать команду gunzip для распаковки файла перед подсчетом его строк!

Подсчет пустых строк в файле

Я показал вам несколько вещей, которые можно сделать с помощью grep, wc и других команд.

И я хочу показать вам еще кое-что, что может оказаться полезным.

Допустим, я хочу подсчитать количество пустых строк в файле.

Синтаксис аналогичен другим командам, которые мы видели до сих пор, с разницей в шаблоне, сопоставляемом с помощью команды grep для определения пустых строк.

Шаблон для определения пустой строки с помощью grep:

grep '^$' <filename>

Это представляет собой пустую строку, поскольку ^ — начало строки, $ — конец строки, и между ними ничего нет.

Итак, если взять в качестве примера файл app_error.log, то полная команда для определения количества пустых строк в этом файле будет выглядеть так:

grep '^$' app_error.log | wc -l

Как мы уже видели, это можно записать с использованием флага -c для grep:

grep -c '^$' app_error.log

Если я хочу вывести количество непустых строк, я могу просто добавить флаг -v для команды grep, которая меняет смысл сопоставления.

По сути, он выбирает строки, которые не соответствуют указанному шаблону:

grep -cv '^$' app_error.log

Имеет ли это смысл?

Заключение

Существует множество способов использования команды wc в системе Linux.

Вы узнали, как использовать его для подсчета строк в файле…

Как объединить его с командой grep, используя конвейер, чтобы подсчитать количество вхождений определенного шаблона в обычном файле и в сжатом файле…

И как узнать количество файлов в каталоге с определенным расширением.

И есть множество других способов его использования.

Written by Иван Васильков

Системный администратор и DevOps с опытом 10+ лет.