Практическое руководство по изучению awk

Из всех Linux команд там (и есть много), то три наиболее квинтэссенция кажется sedawkи grep. Может быть, дело в загадочном звучании их имен, или широте их потенциального использования, или просто их возрасте, но когда кто-то приводит пример команды «Linuxy», обычно это одна из этих трех. И хотя sedи grepесть несколько простых стандартов однострочные, менее престижные awkостается постоянно видными за то , что особенно озадачивает.

Вы, вероятно, будете использовать sedдля быстрой замены строки или grepдля ежедневной фильтрации шаблона. У вас гораздо меньше шансов составить awkкоманду. Я часто задаюсь вопросом, почему это так, и объясняю это несколькими причинами. Во-первых, многие из нас почти не используют sedи grepдля чего-нибудь, кроме некоторых вариаций этих двух команд:

sed -e 's/foo/bar/g' file.txt
$ grep foo file.txt

Таким образом, даже если вы чувствуете себя более комфортно с sedи grep, вы не можете полностью использовать их потенциал. Конечно, необязательно узнавать больше о sedили grep, но иногда я задаюсь вопросом, как я «учу» команды. Вместо того, чтобы изучать, как работает команда, я часто изучаю конкретное заклинание, которое включает команду. В результате я часто чувствую ложное знакомство с командой. Мне кажется, что я знаю команду, потому что я могу назвать три или четыре опции, даже если я не знаю, что они делают, и не могу точно указать на синтаксис.

И я считаю, что это проблема, с которой многие люди сталкиваются, когда сталкиваются с силой и гибкостью awk.

Изучение awk для использования awk

Основы на awkудивление просты. Часто отмечают, что awkэто язык программирования, и хотя он относительно базовый, это правда. Это означает, что вы можете изучать так awkже, как вы изучаете новый язык программирования: изучать его синтаксис с помощью некоторых базовых команд, изучать его словарный запас, чтобы вы могли создавать сложные действия, а затем практиковаться, практиковаться, практиковаться.

Как awk анализирует ввод

Awkвидит ввод, по сути, как массив. При awkсканировании текстового файла каждая строка, по отдельности и последовательно, рассматривается как запись . Каждая запись разбита на поля . Конечно, awkнеобходимо отслеживать эту информацию, и вы можете видеть эти данные с помощью встроенных переменных NR(количество записей) и NF(количество полей). Например, это дает вам количество строк в файле:

awk 'END { print NR;}' example.txt
36

Это также кое-что раскрывает о awkсинтаксисе. Независимо от того, пишете ли вы awkкак однострочник или как автономный скрипт, структура awkинструкции следующая:

pattern or keyword { actions }

В этом примере слово ENDявляется специальным зарезервированным ключевым словом, а не шаблоном. Похожее ключевое слово BEGIN. С обоими этими ключевыми словами awkпросто выполняет действие в фигурных скобках в начале или в конце анализа данных.

Вы можете использовать шаблон в качестве фильтра или квалификатора, чтобы awkвыполнять заданное действие только тогда, когда оно может сопоставить ваш шаблон с текущей записью. Например, предположим, что вы хотите использовать awk, как и вы grep, чтобы найти слово Linux в текстовом файле:

awk '/Linux/ { print $0; }' os.txt
OS: CentOS Linux (10.1.1.8)
OS: CentOS Linux (10.1.1.9)
OS: Red Hat Enterprise Linux (RHEL) (10.1.1.11)
OS: Elementary Linux (10.1.2.4)
OS: Elementary Linux (10.1.2.5)
OS: Elementary Linux (10.1.2.6)

Ведь awkкаждая строка в файле — это запись, а каждое слово в записи — это поле. По умолчанию поля разделяются пробелом. Вы можете изменить это с помощью --field-separatorопции, которая устанавливает для FSпеременной (разделителя полей) все, что вы хотите:

awk --field-separator ':' '/Linux/ { print $2; }' os.txt
 CentOS Linux (10.1.1.8)
 CentOS Linux (10.1.1.9)
 Red Hat Enterprise Linux (RHEL) (10.1.1.11)
 Elementary Linux (10.1.2.4)
 Elementary Linux (10.1.2.5)
 Elementary Linux (10.1.2.6)

В этом примере перед каждым листингом есть пустое место, потому что после каждого двоеточия ( :) в исходном тексте есть пустое место . Однако это не cutтак, поэтому разделитель полей не должен ограничиваться одним символом:

awk --field-separator ': ' '/Linux/ { print $2; }' os.txt
CentOS Linux (10.1.1.8)
CentOS Linux (10.1.1.9)
Red Hat Enterprise Linux (RHEL) (10.1.1.11)
Elementary Linux (10.1.2.4)
Elementary Linux (10.1.2.5)
Elementary Linux (10.1.2.6)

Функции в awk

Вы можете создавать свои собственные функции, awkиспользуя этот синтаксис:

name(parameters) { actions }

Функции важны, потому что они позволяют вам написать код один раз и повторно использовать его в вашей работе. При создании однострочников пользовательские функции немного менее полезны, чем в сценариях, но уже awkопределяют многие функции для вас. Они работают в основном так же, как и любые функции на любом другом языке или в электронной таблице: вы узнаете, в каком порядке функция требует от вас информацию, и вы можете скормить ей все, что захотите, чтобы получить результаты.

Есть функции для выполнения математических операций и обработки строк. Математические часто довольно просты. Вы указываете число, и оно его вычисляет:

awk 'BEGIN { print sqrt(1764); }'
42

Строковые функции могут быть более сложными, но они хорошо документированы в руководстве по GNU awk . Например, splitфункция берет объект, который awkотображается как единое поле, и разбивает его на разные части. Для этого требуется поле, переменная для использования в качестве массива, содержащего каждую часть разбиения, и символ, который вы хотите использовать в качестве разделителя.

Используя выходные данные предыдущих примеров, я знаю, что в самом конце каждой записи есть IP-адрес. В этом случае я могу отправить только последнее поле записи в splitфункцию, указав переменную, NFпотому что она содержит количество полей (и последнее поле должно быть самым большим числом):

awk --field-separator ': ' '/Linux/ { split($NF, IP, "."); print "subnet: " IP[3]; }' os.txt
subnet: 1
subnet: 1
subnet: 1
subnet: 2
subnet: 2
subnet: 2

Функций гораздо больше, и нет причин ограничивать себя одной на блок awkкода. Вы можете создавать сложные конвейеры awkв своем терминале или писать awkсценарии для определения и использования ваших собственных функций.