Привет, Хабр! Когда я только начинал работать с Linux, каждую задачу обрабатывал через кучку пайпов. Потом мой коллега сказал мне: «Завязывай с этим, попробуй awk». Ну, я попробовал. И это действительно удобно. Сегодня я расскажу, как awk может заменить несколько привычных команд bash.
Выборка столбцов
Классика жанра: есть CSV‑файл, и надо взять второй и четвертый столбцы. Обычно вы бы написали:
cut -d',' -f2,4 file.csv
Но! Зачем cut
, если есть awk? Выглядит намного красивее:
awk -F',' '{if (NF >= 4) print $2, $4}' file.csv
Никаких точек с запятыми, странных пайпов. Все в одну строчку. Выглядит приятно.
Фильтрация строк по ключевому слову
Вы смотрите логи. Сервер падает (как обычно), и вы ищете строки с «Error«. Обычно это grep
:
grep "Error" logs.txt
С awk это выглядит так:
awk '/Error/' logs.txt
awk — это почти как SQL для текстовых файлов. Можно использовать любой шаблон
awk '/^Error [0-9]{3}:/' logs.txt
Вот вам и фильтрация ошибок по HTTP-коду.
Подсчёт строк с условием
«Сколько раз я был прав?» — спросите вы после пары ошибок. С grep -c
это просто:
grep -c "Success" logs.txt
А теперь смотрим, как это делает awk:
awk '/Success/ {count++} END {print count}' logs.txt
Здесь важно слово END
. Оно активируется после обработки всех строк.
Замена текста
Допустим, вам нужно заменить «проблема» на «задача» в файле. С sed
это так:
sed 's/проблема/задача/g' file.txt
А вот и awk, который делает то же самое:
awk '{gsub(/проблема/, "задача"); print}' file.txt
Кстати, это прекрасно работает с JSON.
Уникальные строки
Ну кто из нас не сортировал строки через sort | uniq
? Пример:
sort file.txt | uniq
С awk можно проще:
awk '!seen[$0]++' file.txt
seen
— это массив. Если строка ещё не встречалась, мы её выводим.
Подсчёт слов
Надо быстро посчитать, сколько слов в файле? Берем wc -w
:
wc -w file.txt
Но мы тут за awk, так что:
awk '{count += NF} END {print count}' file.txt
NF
— количество полей (читай: слов) в строке. Кажется, что избыточно? Возможно. Но если вы захотите условие «только строки, где слов больше 5», это уже выглядит удобней.
Вывод строк по диапазону
Нужно вывести строки с 10 по 20? Старый добрый sed
:
sed -n '10,20p' file.txt
С awk всё просто:
awk 'NR>=10 && NR<=20' file.txt
NR
— это текущий номер строки.
Вычисление среднего
А вот это совсем интересно. Есть файл с числами в первом столбце, и вы хотите их среднее. Обычно такой Bash:
awk '{sum += $1} END {print sum/NR}' numbers.txt
А теперь сделаем это с проверкой на случай, если файл пустой:
awk '{sum += $1; count++} END {if (count > 0) print sum/count; else print "Нет данных"}' numbers.txt
Конечно, awk — инструмент хороший, но и у него есть свои недостатки.
Обратная сторона awk
-
Производительность на больших данных. Для обработки очень больших файлов awk может быть менее эффективен, чем инструменты вроде
sed
,grep
или того же Python. Иногда проще написать скрипт на Python сpandas
, чем шаманить с awk на терабайтном логе. -
Сложность отладки. Если awk-скрипт становится длинным и запутанным, отладка превращается в головную боль. Нет ни встроенного дебаггера, ни удобных средств для профилирования.
-
Ограниченная поддержка. Несмотря на всю свою мощь, awk не поддерживает сложные структуры данных или современные подходы к программированию (ну, потому что это всё-таки инструмент 70-х годов). Иногда проще подключить полноценный язык программирования.
-
Зависимость от реализации. Существуют разные версии awk (например,
gawk
,mawk
,nawk
), и некоторые возможности могут отличаться между ними. Если ваш скрипт запускается на одном сервере, это не значит, что он так же будет работать на другом.
Такие дела. А какой у вас опыт работы с awk? Делитесь в комментариях.
Приглашаю вас на бесплатные вебинары курса Administrator Linux. Professional:
-
02.12. Введение в Docker. Зарегистрироваться
-
16.12 Репликация в MySQL. Зарегистрироваться
ссылка на оригинал статьи https://habr.com/ru/articles/861572/
Добавить комментарий