C.2. Awk


Awk — это полноценный язык обработки текстовой информации с синтаксисом, напоминающим синтаксис языка C. Он обладает довольно широким набором возможностей, однако, мы рассмотрим лишь некоторые из них — наиболее употребимые в сценариях командной оболочки.

Awk "разбивает" каждую строку на отдельные поля. По-умолчанию, поля — это последовательности символов, отделенные друг от друга пробелами, однако имеется возможность назначения других символов, в качестве разделителя полей. Awk анализирует и обрабатывает каждое поле в отдельности. Это делает его идеальным инструментом для работы со структурированными текстовыми файлами — осбенно с таблицами.

Внутри сценариев командной оболочки, код awk, заключается в "строгие" (одиночные) кавычки и фигурные скобки.

  1. awk '{print $3}' $filename
  2. # Выводит содержимое 3-го поля из файла $filename на устройство stdout.
  3. awk '{print $1 $5 $6}' $filename
  4. # Выводит содержимое 1-го, 5-го и 6-го полей из файла $filename.


Только что, мы рассмотрели действие команды print. Еще, на чем мы остановимся — это переменные. Awk работает с переменными подобно сценариям командной оболочки, но более гибко.

  1. { total += ${column_number} }
Эта команда добавит содержимое переменной column_number к переменной "total". Чтобы, в завершение вывести "total", можно использовать команду END, которая открывает блок кода, отрабатывающий после того, как будут обработаны все входные данные.
  1. END { print total }


Команде END, соответствует команда BEGIN, которая открывает блок кода, отрабатывающий перед началом обработки входных данных.

Следующий пример демонстрирует применение awk для разбора текста в сценариях командной оболочки.

Пример C-1. Подсчет количества символов

  1. #! /bin/sh
  2. # letter-count.sh: Counting letter occurrences in a text file.
  3. #
  4. # Автор: nyal (<a href="mailto:nyal@voila.fr">nyal@voila.fr</a>).
  5. # Используется с разрешения автора сценария.
  6. # Комментарии добавлены автором документа.
  7. INIT_TAB_AWK=""
  8. count_case=0
  9. FILE_PARSE=$1
  10. E_PARAMERR=65
  11. usage()
  12. {
  13.     echo "Порядок использования: letter-count.sh имя_файла символы" 2>&1
  14.     # Например:   ./letter-count.sh filename.txt a b c
  15.     exit $E_PARAMERR  # Вызов сценария без аргументов.
  16. }
  17. if [ ! -f "$1" ] ; then
  18.     echo "Файл $1 не найден." 2>&1
  19.     usage                 # Вывод сообщения и выход.
  20. fi
  21. if [ -z "$2" ] ; then
  22.     echo "$2: Не заданы символы для поиска." 2>&1
  23.     usage
  24. fi
  25. shift                      # Символы заданы.
  26. for letter in `echo $@`    # Для каждого из них . . .
  27.   do
  28.   INIT_TAB_AWK="$INIT_TAB_AWK tab_search[${count_case}] = \"$letter\"; final_tab[${count_case}] = 0; "
  29.   # Передается как параметр в сценарий awk ниже.
  30.   count_case=`expr $count_case + 1`
  31. done
  32. # DEBUG:
  33. # echo $INIT_TAB_AWK;
  34. cat $FILE_PARSE |
  35. # Передать заданый файл по конвейеру в сценарий awk.
  36. # --------------------------------------------------------------------------------
  37. # От переводчика:
  38. #    В оригинальном тексте сценария стоит следующая строка:
  39. #awk -v tab_search=0 -v final_tab=0 -v tab=0 -v nb_letter=0 -v chara=0 -v chara2=0 \
  40. #
  41. #    с моим gawk 3.1.3 сценарий делается неработоспособным
  42. #    поэтому я взял на себя смелость несколько подправить эту строку,
  43. #    в результате она получилась такой:
  44. awk -v nb_letter=0 -v chara=0 -v chara2=0 \
  45. "BEGIN { $INIT_TAB_AWK } \
  46. { split(\$0, tab, \"\"); \
  47. for (chara in tab) \
  48. { for (chara2 in tab_search) \
  49. { if (tab_search[chara2] == tab[chara]) { final_tab[chara2]++ } } } } \
  50. END { for (chara in final_tab) \
  51. { print tab_search[chara] \" => \" final_tab[chara] } }"
  52. # --------------------------------------------------------------------------------
  53. #  Ничего сложного. . .
  54. #+ Циклы for, проверка условия if, и пара специфических функций.
  55. exit $?

Более простые примеры использования awk в сценариях командной оболочки, вы найдете в:

  1. Пример 11-11

  2. Пример 16-7

  3. Пример 12-27

  4. Пример 33-3

  5. Пример 9-22

  6. Пример 11-17

  7. Пример 27-2

  8. Пример 27-3

  9. Пример 10-3

  10. Пример 12-45

  11. Пример 9-27

  12. Пример 12-4

  13. Пример 9-12

  14. Пример 33-12

  15. Пример 10-8



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