Awk -- это полноценный язык обработки текстовой информации с синтаксисом, напоминающим синтаксис языка C. Он обладает довольно широким набором возможностей, однако, мы рассмотрим лишь некоторые из них -- наиболее употребимые в сценариях командной оболочки.
Awk "разбивает" каждую строку на отдельные поля. По-умолчанию, поля -- это последовательности символов, отделенные друг от друга пробелами, однако имеется возможность назначения других символов, в качестве разделителя полей. Awk анализирует и обрабатывает каждое поле в отдельности. Это делает его идеальным инструментом для работы со структурированными текстовыми файлами -- осбенно с таблицами.
Внутри сценариев командной оболочки, код awk, заключается в "строгие" (одиночные) кавычки и фигурные скобки.
awk '{print $3}' $filename # Выводит содержимое 3-го поля из файла $filename на устройство stdout. awk '{print $1 $5 $6}' $filename # Выводит содержимое 1-го, 5-го и 6-го полей из файла $filename.
Только что, мы рассмотрели действие команды print. Еще, на чем мы остановимся -- это переменные. Awk работает с переменными подобно сценариям командной оболочки, но более гибко.
{ total += ${column_number} }
Эта команда добавит содержимое переменной column_number к переменной "total". Чтобы, в завершение вывести "total", можно использовать команду END, которая открывает блок кода, отрабатывающий после того, как будут обработаны все входные данные.
END { print total }
Команде END, соответствует команда BEGIN, которая открывает блок кода, отрабатывающий перед началом обработки входных данных.
Следующий пример демонстрирует применение awk для разбора текста в сценариях командной оболочки.
Пример C-1. Подсчет количества символов
#! /bin/sh # letter-count.sh: Counting letter occurrences in a text file. # # Автор: nyal (nyal@voila.fr). # Используется с разрешения автора сценария. # Комментарии добавлены автором документа. INIT_TAB_AWK="" count_case=0 FILE_PARSE=$1 E_PARAMERR=65 usage() { echo "Порядок использования: letter-count.sh имя_файла символы" 2>&1 # Например: ./letter-count.sh filename.txt a b c exit $E_PARAMERR # Вызов сценария без аргументов. } if [ ! -f "$1" ] ; then echo "Файл $1 не найден." 2>&1 usage # Вывод сообщения и выход. fi if [ -z "$2" ] ; then echo "$2: Не заданы символы для поиска." 2>&1 usage fi shift # Символы заданы. for letter in `echo $@` # Для каждого из них . . . do INIT_TAB_AWK="$INIT_TAB_AWK tab_search[${count_case}] = \"$letter\"; final_tab[${count_case}] = 0; " # Передается как параметр в сценарий awk ниже. count_case=`expr $count_case + 1` done # DEBUG: # echo $INIT_TAB_AWK; cat $FILE_PARSE | # Передать заданый файл по конвейеру в сценарий awk. # -------------------------------------------------------------------------------- # От переводчика: # В оригинальном тексте сценария стоит следующая строка: #awk -v tab_search=0 -v final_tab=0 -v tab=0 -v nb_letter=0 -v chara=0 -v chara2=0 \ # # с моим gawk 3.1.3 сценарий делается неработоспособным # поэтому я взял на себя смелость несколько подправить эту строку, # в результате она получилась такой: awk -v nb_letter=0 -v chara=0 -v chara2=0 \ "BEGIN { $INIT_TAB_AWK } \ { split(\$0, tab, \"\"); \ for (chara in tab) \ { for (chara2 in tab_search) \ { if (tab_search[chara2] == tab[chara]) { final_tab[chara2]++ } } } } \ END { for (chara in final_tab) \ { print tab_search[chara] \" => \" final_tab[chara] } }" # -------------------------------------------------------------------------------- # Ничего сложного. . . #+ Циклы for, проверка условия if, и пара специфических функций. exit $?
Более простые примеры использования awk в сценариях командной оболочки, вы найдете в:
Это все, что я хотел рассказать об awk. Дополнительные ссылки на информацию об awk, вы найдете в разделе Библиография.