Введение
Небольшие команды Linux становятся гораздо полезнее, когда оболочка координирует их работу. Команда сообщает об успехе или ошибке с помощью кода завершения; операторы последовательного выполнения определяют, какая команда запустится следующей; конвейер передаёт стандартный вывод одной команды на стандартный ввод другой.
Вы будете изучать эти возможности постепенно, а затем с помощью grep, cut, wc, sort и uniq преобразуете небольшой набор данных о событиях службы. В следующих практических занятиях фильтры обработки текста будут рассмотрены подробнее, поэтому здесь основное внимание уделяется передаче данных и управлению выполнением команд.
Просмотр кода завершения команды
На этом шаге вы сопоставите видимый результат выполнения команды с числовым статусом, который сохраняет оболочка.
Код завершения 0 означает успех, а ненулевое значение — что команда не смогла выполнить запрошенную операцию. Выполните успешную проверку файла и сразу выведите $?, в котором хранится последний код завершения:
cd /home/labex/project/pipeline-lab
test -f events.csv
echo $?
В выводе появится 0. Теперь проверьте отсутствующий файл:
test -f missing.csv
echo $?
Код завершения будет ненулевым. Читайте значение $? сразу после нужной команды, потому что каждая следующая команда заменяет его.
Создайте удобный для проверки результат с помощью конструкции if. Полные сценарии оболочки вы изучите позже; здесь конструкция лишь преобразует код завершения в текст:
if test -f events.csv; then echo "events.csv is ready"; else echo "events.csv is missing"; fi > status-result.txt
cat status-result.txt
Управление следующей выполняемой командой
На этом шаге вы сравните безусловные и условные операторы команд.
Точка с запятой запускает следующую команду независимо от результата предыдущей:
false; echo "semicolon continues"
&& запускает правую команду только после успешного выполнения левой:
test -f events.csv && echo "input found"
test -f missing.csv && echo "you should not see this"
|| запускает правую команду только после ошибки левой:
test -f missing.csv || echo "input missing"
С помощью этих операторов можно выразить простое решение об успехе или ошибке. Скопируйте набор данных только при наличии исходного файла; в противном случае выведите сообщение об ошибке:
test -f events.csv && cp events.csv working.csv || echo "Copy failed"
Проверьте, что защищённая условием копия совпадает с исходным файлом:
cmp events.csv working.csv && echo "guarded copy matches" > sequence-result.txt
cat sequence-result.txt
Для сложной логики используйте понятную конструкцию if: длинные цепочки && и || могут стать неоднозначными.
Передача вывода через конвейер
На этом шаге вы соедините команды с помощью | и увидите, как каждый этап сужает поток данных.
Левая команда записывает стандартный вывод в конвейер, а правая читает эти данные как стандартный ввод. Выберите только записи ERROR:
cd /home/labex/project/pipeline-lab
cat events.csv | grep ',ERROR,'
grep умеет читать файл напрямую, поэтому следующая сокращённая форма даёт тот же результат:
grep ',ERROR,' events.csv
Добавьте wc -l, чтобы подсчитать совпавшие строки:
grep ',ERROR,' events.csv | wc -l
Сохраните и отфильтрованный поток, и его количество. tee дублирует стандартный ввод: одну копию он записывает в error-events.csv, а другую передаёт дальше через стандартный вывод. Поэтому последний wc -l подсчитывает ровно те строки, которые были сохранены:
grep ',ERROR,' events.csv | tee error-events.csv | wc -l > error-count.txt
cat error-events.csv
cat error-count.txt
После выполнения конвейера просмотрите оба файла. error-events.csv содержит совпавшие записи, а error-count.txt — их количество.
Извлечение полей с помощью cut
На этом шаге вы будете рассматривать каждую строку CSV как набор полей, разделённых разделителем.
cut -d, -f1 использует запятую как разделитель и выводит поле 1 — имя службы:
cd /home/labex/project/pipeline-lab
cut -d, -f1 events.csv
Выведите вместе поля службы и уровня важности:
cut -d, -f1,2 events.csv
Объедините фильтрацию и извлечение, чтобы получить список только тех служб, которые создали предупреждения:
grep ',WARN,' events.csv | cut -d, -f1
Сохраните этот промежуточный результат:
grep ',WARN,' events.csv | cut -d, -f1 > warning-services.txt
cat warning-services.txt
cut хорошо подходит для простых записей, в которых разделитель не встречается внутри поля. Для более сложных форматов могут потребоваться awk или инструмент, учитывающий структуру конкретного формата.
Сортировка и подсчёт повторяющихся значений
На этом шаге вы создадите полный конвейер подсчёта частот и поймёте, почему перед uniq нужна сортировка.
uniq объединяет только соседние одинаковые строки. Сначала извлеките имена служб, затем отсортируйте их, чтобы одинаковые значения оказались рядом:
cd /home/labex/project/pipeline-lab
cut -d, -f1 events.csv | sort
Добавьте uniq -c, чтобы подсчитать каждую последовательность одинаковых имён:
cut -d, -f1 events.csv | sort | uniq -c
Отсортируйте количества по числовому значению в порядке убывания. sort -k1,1nr использует первое поле как ключ с числовой сортировкой в обратном порядке:
cut -d, -f1 events.csv | sort | uniq -c | sort -k1,1nr
Сохраните итоговый отчёт:
cut -d, -f1 events.csv | sort | uniq -c | sort -k1,1nr > service-frequency.txt
cat service-frequency.txt
Читайте этот конвейер слева направо: извлечь → отсортировать → подсчитать соседние дубликаты → упорядочить количества.
Итоги
Вы использовали код завершения как сигнал успеха оболочки, управляли выполнением с помощью ;, && и ||, а также создавали конвейеры с понятными этапами. Затем вы фильтровали записи, извлекали поля, подсчитывали строки, сортировали значения и подсчитывали дубликаты — это именно те базовые приёмы, которые понадобятся в следующем Challenge по конвейерам обработки данных.



