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, соответствует команда BEGIN, которая открывает блок кода, отрабатывающий перед началом обработки входных данных.
Следующий пример демонстрирует применение awk для разбора текста в сценариях командной оболочки.
Пример C-1. Подсчет количества символов
#! /bin/sh
# letter-count.sh: Counting letter occurrences in a text file.
#
# Автор: nyal (<a href="mailto:nyal@voila.fr">nyal@voila.fr</a>).
# Используется с разрешения автора сценария.
# Комментарии добавлены автором документа.
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 в сценариях командной оболочки, вы найдете в:
-
Пример 11-11
-
Пример 16-7
-
Пример 12-27
-
Пример 33-3
-
Пример 9-22
-
Пример 11-17
-
Пример 27-2
-
Пример 27-3
-
Пример 10-3
-
Пример 12-45
-
Пример 9-27
-
Пример 12-4
-
Пример 9-12
-
Пример 33-12
-
Пример 10-8
Это все, что я хотел рассказать об awk. Дополнительные ссылки на информацию об awk, вы найдете в разделе Библиография.
Последние комментарии