Показать статистику
0 голосов
от (2.7тыс. баллов)
Здравствуйте. Прошу рассказать подробнее об awk, как  с  помощью awk извлекать данные и создавать отчеты, писать программы?
1.5тыс. просмотров 1 ответов

1 Ответ

0 голосов
от (26.4тыс. баллов)

AWK - это мощный язык программирования, основанный на данных, который берет свое начало с первых дней существования Unix. Первоначально он был разработан для написания «однострочных» программ, но с тех пор превратился в полноценный язык программирования . AWK получил свое название от инициалов своих авторов - Aho, Weinberger и Kernighan. Команда awk в Linux и других системах Unix вызывает интерпретатор, выполняющий сценарии AWK. В последних системах существует несколько реализаций awk, таких как gawk (GNU awk), mawk (Minimal awk) и nawk (New awk). Посмотрите приведенные ниже примеры, если вы хотите освоить awk.

Понимание программ AWK

Программы, написанные на awk, состоят из правил, которые представляют собой просто пару шаблонов и действий. Шаблоны сгруппированы в фигурную скобку {}, и часть действия запускается всякий раз, когда awk находит тексты, соответствующие шаблону. Хотя awk был разработан для написания однострочников, опытные пользователи могут легко писать сложные сценарии с его помощью.

image

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

Практические примеры использования команды awk в Linux

Администраторы обычно используют awk для извлечения данных и создания отчетов наряду с другими типами манипуляций с файлами. 

Внимательно следуйте командам и попробуйте их в своем терминале для полного понимания.

Распечатайте определенные поля из текстового вывода

Наиболее широко используемые команды Linux отображают свои результаты в различных полях. Обычно мы используем команду Linux cut для извлечения определенного поля из таких данных. Тем не менее, приведенная ниже команда показывает, как это сделать, используя команду awk.

$ who | awk '{print $1}'

Эта команда будет отображать только первое поле из вывода команды who. Таким образом, вы просто получите имена всех зарегистрированных пользователей. Здесь $ 1 представляет первое поле. Вам нужно использовать $ N, если вы хотите извлечь N-ое поле.

Печать нескольких полей из текстового вывода

Интерпретатор awk позволяет нам печатать любое количество полей. В приведенных ниже примерах показано, как извлечь первые два поля из вывода команды who.

$ who | awk '{print $1, $2}'

Вы также можете контролировать порядок полей вывода. В следующем примере сначала отображается второй столбец, созданный командой who, а затем первый столбец во втором поле.

$ who | awk '{print $2, $1}'

Просто пропустите параметры поля ( $ N ), чтобы отобразить все данные.

Используйте Оператор BEGIN

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

BEGIN { Actions}

{ACTION}

Действия, которые формируют раздел BEGIN, всегда запускаются. Затем awk читает оставшиеся строки одну за другой и видит, нужно ли что-то делать.

$ who | awk 'BEGIN {print "User\tFrom"} {print $1, $2}'

Приведенная выше команда помечает два выходных поля, извлеченных из вывода команды who.

Используйте оператор END 

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

$ who | awk 'BEGIN {print "User\tFrom"} {print $1, $2} END {print "--COMPLETED--"}'

Приведенная выше команда добавит данную строку в конец вывода.

Поиск с использованием шаблонов

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

$ who | awk '/mary/ {print}'

Эта команда увидит, вошел ли пользователь в данный момент в систему или нет. Он выведет всю строку, если найдено какое-либо совпадение.

Извлечение информации из файлов

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

$ awk '/hello/ {print}' /usr/share/dict/american-english

Эта команда ищет шаблон 'hello' в файле англо-американского словаря. Он доступен в большинстве дистрибутивов на основе Linux . Таким образом, вы можете легко попробовать программы awk для этого файла.

Считывать скрипт AWK из исходного файла

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

$ awk -f script-file

$ awk --file script-file

Опция -f или –file позволяет нам указать файл программы. Однако вам не нужно использовать кавычки ('') внутри файла скрипта, поскольку оболочка Linux не будет интерпретировать программный код таким образом.

Установите разделитель поля ввода

Разделитель полей - это разделитель, который разделяет входную запись. Мы можем легко указать разделители полей для awk, используя опцию -F или –field-separator . Проверьте следующие команды, чтобы увидеть, как это работает.

$ echo "This-is-a-simple-example" | awk -F - ' {print $1} '

$ echo "This-is-a-simple-example" | awk --field-separator - ' {print $1} '

Он работает так же при использовании файлов сценариев.

Распечатывать информацию в зависимости от условий

Мы обсуждали команду Linux cut в этом руководстве. Теперь рассмотрим как извлекать информацию с помощью awk, только когда определенные критерии соответствуют. Мы будем использовать тот же тестовый файл, который мы использовали ранее. Так что зайдите туда и сделайте копию файла test.txt .

$ awk '$4 > 50' test.txt

Эта команда выведет все страны из файла test.txt, в котором проживает более 50 миллионов человек.

Распечатайте информацию путем сравнения регулярных выражений

Следующая команда awk проверяет, содержит ли третье поле любой строки шаблон «Лира», и печатает всю строку, если найдено совпадение. Мы снова используем файл test.txt, используемый для иллюстрации команды cut в Linux . Поэтому убедитесь, что у вас есть этот файл, прежде чем продолжить.

$ awk '$3 ~ /Lira/' test.txt

Вы можете распечатать только определенную часть любого совпадения, если хотите.

Подсчитайте общее количество строк на входе

Команда awk имеет много переменных специального назначения, которые позволяют нам легко выполнять многие сложные задачи. Одной из таких переменных является NR, которая содержит номер текущей строки.

$ awk 'END {print NR} ' test.txt

Эта команда выведет количество строк в нашем файле test.txt. Сначала он выполняет итерацию по каждой строке, и как только он достигнет END, он напечатает значение NR, которое содержит общее количество строк в этом случае.

Установите разделитель поля вывода

Ранее мы рассматривали как выбирать разделители входных полей, используя опцию -F или –field-separator . Команда awk также позволяет нам указать разделитель поля вывода. Приведенный ниже пример демонстрирует это на практическом примере.

$ date | awk 'OFS="-" {print$2,$3,$6}'

Эта команда выводит текущую дату в формате дд-мм-гг. Запустите программу date без awk, чтобы увидеть, как выглядит вывод по умолчанию.

 Использование If Construct

Как и другие популярные языки программирования , awk также предоставляет пользователям конструкции if-else. Оператор if в awk имеет следующий синтаксис.

if (expression)

{

  first_action

  second_action

}

Соответствующие действия выполняются только в том случае, если условное выражение истинно. Приведенный ниже пример демонстрирует это с помощью нашего справочного файла test.txt .

$ awk '{ if ($4>100) print }' test.txt

Вам не нужно строго поддерживать отступ.

Использование конструкций If-Else

Вы можете построить полезные лестницы if-else, используя приведенный ниже синтаксис. Они полезны при разработке сложных сценариев awk, которые работают с динамическими данными.

if (expression)

  first_action

else

  second_action

$ awk '{ if ($4>100) print; else print }' test.txt

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

Установите ширину поля

Иногда входные данные довольно беспорядочные, и пользователям может быть трудно их визуализировать в своих отчетах. К счастью, awk предоставляет мощную встроенную переменную под названием FIELDWIDTHS, которая позволяет нам определять разделенный пробелами список значений ширины.

$ echo 5675784464657 | awk 'BEGIN {FIELDWIDTHS= "3 4 5"} {print $1, $2, $3}'

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

 Установите разделитель записей

RS или Record Separator - это другая встроенная переменная, которая позволяет нам указать, как разделяются записи. Давайте сначала создадим файл, который будет демонстрировать работу этой переменной awk.

$ cat new.txt

Melinda James

23 New Hampshire

(222) 466-1234

Daniel James

99 Phonenix Road

(322) 677-3412

$ awk 'BEGIN{FS="\n"; RS=""} {print $1,$3}' new.txt

Эта команда проанализирует документ и выдаст имя и адрес для двух человек.

 

от (26.4тыс. баллов)
0

Продолжая тему...

Переменные среды печати

Команда awk в Linux позволяет легко печатать переменные окружения, используя переменную ENVIRON. Команда ниже демонстрирует, как использовать это для печати содержимого переменной PATH.

$ awk 'BEGIN{ print ENVIRON["PATH"] }'

Вы можете распечатать содержимое любых переменных среды, подставив аргумент переменной ENVIRON. Приведенная ниже команда печатает значение переменной среды HOME.

$ awk 'BEGIN{ print ENVIRON["HOME"] }'

Опустить некоторые поля из вывода

Команда awk позволяет нам пропустить определенные строки в нашем выводе. Следующая команда продемонстрирует это, используя наш справочный файл test.txt .

$ awk -F":" '{$2=""; print}' test.txt

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

$ awk -F":" '{$2="";$3="";print}' test.txt

Удалить пустые строки

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

$ awk '/^[ \t]*$/{next}{print}' new.txt

Вывод многих команд Linux содержит конечные пробелы. Мы можем использовать команду awk в Linux для удаления таких пробелов, как пробелы и табуляции(tab). Проверьте приведенную ниже команду, чтобы увидеть, как решать такие проблемы с помощью awk.

$ awk '{sub(/[ \t]*$/, "");print}' new.txt test.txt

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

Проверьте количество полей в каждой строке

Мы можем легко проверить, сколько полей в строке, используя простую однострочную строку awk. Есть много способов сделать это, но мы будем использовать некоторые встроенные переменные awk для этой задачи. Переменная NR дает нам номер строки, а переменная NF - количество полей.

$ awk '{print NR,"-->",NF}' test.txt

Теперь мы можем подтвердить, сколько полей в каждой строке в нашем документе test.txt . Поскольку каждая строка этого файла содержит 5 полей, мы уверены, что команда работает должным образом.

Проверьте текущее имя файла

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

$ awk '{print FILENAME}' test.txt

$ awk '{print FILENAME}' test.txt new.txt

Приведенные выше команды выводят имя файла, над которым работает awk каждый раз, когда он обрабатывает новую строку входных файлов.

Проверьте количество обработанных записей

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

$ awk '{print "Processing Record - ",NR;} END {print "\nTotal Records Processed:", NR;}' test.txt

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

Распечатайте общее количество символов в записи

Язык awk предоставляет удобную функцию length (), которая сообщает нам, сколько символов присутствует в записи. Это очень полезно в ряде сценариев. Взгляните на следующий пример, чтобы увидеть, как это работает.

$ echo "A random text string..." | awk '{ print length($0); }'
$ awk '{ print length($0); }' /etc/passwd

Приведенная выше команда напечатает общее количество символов, присутствующих в каждой строке входной строки или файла.

Распечатать все строки длиннее указанной длины

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

$ echo "A random text string..." | awk 'length($0) > 10'

$ awk '{ length($0) > 5; }' /etc/passwd

Вы можете добавить дополнительные параметры и / или аргументы, чтобы настроить команду в соответствии с вашими требованиями.

Распечатайте количество строк, символов и слов

Следующая команда awk в Linux печатает количество строк, символов и слов в заданном вводе. Она использует переменную NR, а также некоторую базовую арифметику для выполнения этой операции.

$ echo "This is a input line..." | awk '{ w += NF; c += length + 1 } END { print NR, w, c }'

Она показывает, что во входной строке присутствуют 1 строка, 5 слов и ровно 24 символа.

Рассчитайте частоту слов

Мы можем объединить ассоциативные массивы и цикл for в awk для вычисления частоты слова в документе. Следующая команда может показаться немного сложной, но она довольно проста, если вы четко понимаете основные конструкции.

$ awk 'BEGIN {FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) words[tolower($i)]++ } END { for (i in words) print i, words[i] }' test.txt

Если у вас возникли проблемы с однострочным фрагментом, скопируйте следующий код в новый файл и запустите его с использованием исходного кода.

$ cat > frequency.awk

BEGIN {

FS="[^a-zA-Z]+"

}

{

for (i=1; i<=NF; i++)

words[tolower($i)]++

}

END {

for (i in words)

print i, words[i]

}

Затем запустите его, используя опцию -f .

$ awk -f frequency.awk test.txt

 

от (26.4тыс. баллов)
0

Переименуйте файлы, используя AWK

Команда awk может использоваться для переименования всех файлов, соответствующих определенным критериям. Следующая команда показывает, как использовать awk для переименования всех файлов .MP3 в каталоге в файлы .mp3.

$ touch {a,b,c,d,e}.MP3

$ ls *.MP3 | awk '{ printf("mv \"%s\" \"%s\"\n", $0, tolower($0)) }'

$ ls *.MP3 | awk '{ printf("mv \"%s\" \"%s\"\n", $0, tolower($0)) }' | sh

Сначала мы создали несколько демонстрационных файлов с расширением .MP3. Вторая команда показывает пользователю, что происходит при успешном переименовании. Наконец, последняя команда выполняет операцию переименования с помощью команды mv в Linux.

Распечатать квадратный корень числа

AWK предлагает несколько встроенных функций для работы с числами. Одним из них является функция sqrt (). Это C-подобная функция, которая возвращает квадратный корень из данного числа. Взгляните на следующий пример, чтобы увидеть, как это работает в целом.

$ awk 'BEGIN{ print sqrt(36); print sqrt(0); print sqrt(-16) }'

Поскольку вы не можете определить квадратный корень из отрицательного числа, в выводе вместо sqrt будет отображаться специальное ключевое слово «nan» (-12)

Напечатайте логарифм числа

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

$ awk 'BEGIN{ print log(36); print log(0); print log(-16) }'

Вы должны увидеть логарифм 36 и убедиться, что логарифм 0 равен бесконечности, а лог отрицательного значения - «Not a Number» или nan.

Распечатайте экспоненту числа

Экспоненциальный ос номер n обеспечивает значение e^n. Обычно используется в сценариях awk, которые имеют дело с большими цифрами или сложной арифметической логикой. Мы можем сгенерировать экспоненту числа, используя встроенную функцию awk exp ().

$ awk 'BEGIN{ print exp(30); print log(0); print exp(-16) }'

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

Генерация случайных чисел с помощью AWK

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

$ awk 'BEGIN{ print rand(); print rand()*99 }'

Функция rand () не нуждается в аргументе. Кроме того, числа, сгенерированные этой функцией, не являются абсолютно случайными, а скорее псевдослучайными. Кроме того, довольно легко предсказать эти числа от запуска к запуску. Таким образом, вы не должны полагаться на них для чувствительных расчетов.

Красный предупреждающий цвет компилятора

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

$ gcc -Wall main.c |& awk '/: warning:/{print "\x1B[01;31m" $0 "\x1B[m";next;}{print}'

Эта команда полезна, если вы хотите точно указать предупреждения компилятора. Вы можете использовать эту команду с любым компилятором, кроме gcc, просто измените шаблон /: warning:/  для отражения этого конкретного компилятора.

Распечатайте информацию UUID файловой системы

UUID или универсальный уникальный идентификатор - это число, которое можно использовать для идентификации ресурсов, таких как файловая система Linux . Мы можем просто напечатать информацию UUID нашей файловой системы, используя следующую команду Linux awk.

$ awk '/UUID/ {print $0}' /etc/fstab

Эта команда ищет текстовый UUID в файле / etc / fstab, используя шаблоны awk. Она возвращает комментарий из файла, который нам не интересен. Команда ниже гарантирует, что мы получим только те строки, которые начинаются с UUID.

$ awk '/^UUID/ {print $1}' /etc/fstab

Она ограничивает вывод первым полем. Таким образом, мы получаем только номера UUID.

Распечатать версию образа ядра Linux

Различные образы ядра Linux используются различными дистрибутивами Linux. Мы можем легко распечатать точный образ ядра, на котором основана наша система, используя awk. Проверьте следующую команду, чтобы увидеть, как это работает в целом.

$ uname -a | awk '{print $3}'

Сначала мы выполнили команду uname с параметром -a, а затем передали эти данные в awk. Затем мы извлекли информацию о версии образа ядра с помощью awk.

Добавьте номера строк перед строками

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

$ awk '{ print FNR ". " $0 ;next}{print}' test.txt

Приведенная выше команда добавит номер строки перед каждой из строк в нашем справочном файле test.txt. Для этого используется встроенная переменная awk FNR.

Распечатайте файл после сортировки содержимого

Мы также можем использовать awk для печати отсортированного списка всех строк. Следующие команды печатают названия всех стран в нашем test.txt в отсортированном порядке.

$ awk -F ':' '{ print $1 }' test.txt | sort

Следующая команда напечатает имя пользователя для всех пользователей из файла /etc/passwd.

$ awk -F ':' '{ print $1 }' /etc/passwd | sort

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

Распечатать страницу руководства

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

$ man awk

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

Распечатать страницу справки

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

$ awk -h 

$ awk --help

Обратитесь к этой странице, если вы хотите краткий обзор всех доступных опций для awk.

 Версия для печати информации

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

$ awk -V

$ awk --version

Подводя итог

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

Поскольку AWK сам по себе является полноценным языком программирования, существует несколько способов выполнить одну и ту же работу в зависимости от ваших навыков и опыта.

...