- AWK: Примеры программ
- Способы запуска awk-программ
- Фильтрация строк с помощью awk
- Отбор строк, соответствующих регулярному выражению
- Отбор строк, НЕ соответствующих регулярному выражению
- Отбор строк из заданного диапазона
- Комбинирование условий фильтрации
- Отбор строк по условиям относительно отдельных слов
- Отбор строк на основе числовых характеристик
- Работа со строками в awk
- Форматированный вывод
- Функции преобразования
- Условные конструкции
- Переменные
- Циклы
- Нестандартный разделитель слов
- Комбинирование фильтров и команд печати
- Awk вывести всю строку
- II. Язык обработки шаблонов awk
- 1. Структура awk-программы
- 2. Вызов awk
- 3. awk-переменные и выражения
- 4. Примеры awk-программ
- 5. Селекторы
- 6. Еще примеры
- 7. Действия
- Операторы управления
- Структурные операторы
- 8. Ввод и вывод данных
- 9. Встроенные функции
AWK: Примеры программ
Утилита awk является примером классического приложения Linux для обработки текста. Она весьма универсальна и эффективна, хоть и не предоставляет полноценный язык программирования. Однако будьте уверены, что ее возможностей вполне хватит для решения многих задач автоматизированной обработки текста (особенно при комбинировании с другими консольными утилитами).
Способы запуска awk-программ
Если awk -программа достаточно простая и короткая, то ее код можно набрать прямо в консоли:
В качестве входных данных для awk можно использовать не только текстовые файлы, но и вывод в стандартный поток других приложений:
В случае, когда код awk -программы достаточно объемный или должен быть сохранен для повторного использования, его можно вызывать из файла с ключом -f :
Для проведения экспериментов используем файл test.cpp , на котором будем проверять результаты работы awk — программ:
Реклама
Фильтрация строк с помощью awk
В первую очередь awk позволяет отбирать строки из текста на основе регулярных выражений и некоторых числовых условий.
Отбор строк, соответствующих регулярному выражению
Например, чтобы получить все строки файла test.cpp , содержащие директиву препроцессора #include , воспользуемся следующей командой:
Регулярное выражение записывается между двумя символами / . В результате получим:
Отбор строк, НЕ соответствующих регулярному выражению
Чтобы оставить все строки, которые не соответствуют регулярному выражению, воспользуйтесь командой из предыдущего подраздела и поставьте в начало awk -кода восклицательный знак. Например, так мы исключим все закомментированные строки:
Вот что осталось:
Отбор строк из заданного диапазона
Определить диапазон строк для вывода на экран можно с помощью двух регулярных выражений, записанных через запятую. В качестве примера найдем определение всех функций, возвращающих int :
Комбинирование условий фильтрации
Для проверки строк сразу по нескольким условиям используйте операторы && (И) и || (ИЛИ) .
Следующая команда выводит все комментарии, которые не содержат main :
Ранее мы искали диапазон строк по двум регулярным выражениям, но если номера строк, которые нужно вывести, известные заранее, то все упрощается:
NR — переменная awk , которая определяет номер строки. Таким образом, представленный код выводит 5-ую и 6-ую строки:
Отбор строк по условиям относительно отдельных слов
Awk может фильтровать текст не только по строкам, но и по отдельным словам. На i -ое слово в строке можно сослаться с помощью $i . Нумерация начинается с единицы, а $0 определяет содержимое всей строки. Количество слов в строке определяется с помощью переменной NF , поэтому $NF указывает на последнее слово. Например, найдем строки, первым словом которых является int или void :
Соответствующий вывод на консоль:
Однако проще использовать проверку по регулярному выражению для слова. Для этого в awk предусмотрен специальный оператор
, который нужно поставить между переменной, указывающей на слово, и регулярным выражением. В качестве примера перепишем предыдущую команду в более компактном виде:
Отбор строк на основе числовых характеристик
В awk доступны арифметические операторы языка C, что открывает свободу действий. Пример ниже выводит все четные строки ( NR — номер строки):
Следующая awk -программа выводит все строки, у которых длина 1-ого слова равна трем:
В результате получаем:
Далее приводится код для вывода строк, состоящих из двух слов ( NF — количество слов в строке):
И соответствующий вывод:
Реклама
Работа со строками в awk
Как вы могли убедиться, awk обладает неплохим набором функций для фильтрации строк текста. Однако для этих строк еще можно выполнять различные преобразования. Команды для работы со строками должны быть обернуты в фигурные скобки < . >. Код в скобках последовательно вызывается для каждой строки обрабатываемого текста.
Форматированный вывод
В awk имеется прямой аналог функции printf() языка C . В качестве примера выведем в начале каждой строки ее номер:
Вот что получили:
Функции преобразования
Кроме printf() есть в awk и другие функции. Например, print() и toupper() :
Условные конструкции
В awk -программах доступны операторы if-else . Например, следующий код выводит без изменения строки, у которых на 1-ой позиции стоит int , а на последней — < , иначе на консоль отправляется --- :
Выполнение кода приводит к выводу следующего:
Переменные
Доступны в awk -программах и переменные, которые не требуется предварительно объявлять. Следующий код для подсчета количества строк и слов в тексте поместим в файл stat.awk :
Тогда его вызов осуществляется следующим образом:
Фильтр END указывает, что код в скобках после него должен выполняться только после прохода всех строк. Доступен в awk и фильтр BEGIN , поэтому в более общем случае программа принимает вид:
Обратите внимание, что посчитать строки и слова в тексте намного проще с помощью wc :
Циклы
В awk -программах вам также доступны циклы for и while в стиле C . Для примера выведем все строки в обратном порядке. Создадим файл reverse.awk следующего содержимого:
Вызовем программу следующий образом:
В результате слова в каждой строке будут выведены в обратном порядке:
Нестандартный разделитель слов
По умолчанию awk в качестве разделителя слов использует пробельные символы, однако такое поведение можно изменить. Для этого воспользуйтесь ключом -F , после которого укажите строку, определяющую разделитель. Например, следующая программа выводит название группы и ее пользователей (если в группе есть пользователи) из файла /etc/group , применяя в качестве разделителя символ двоеточия:
Комбинирование фильтров и команд печати
Все рассмотренные ранее фильтры можно использовать совместно с командами обработки строк. Достаточно записать ограничения перед фигурными скобками. Ниже представлен пример для вывода первых 9 строк вывода команды ps , содержащей информацию о пользователе, идентификаторе процесса и имени команды:
Источник
Awk вывести всю строку
Команда имеет формат:
Команда копирует файлы (по умолчанию со стандартного входа) на стандартный выход, редактирует их в соответствии со своими(!) командами, размещенными в «script» (в командном файле или строке редактора [а не shell!]). По флагу «-f» берет берет файл команд из файла «sfile»; Если есть только опция «-e script», то флаг «-e» можно опустить. Флаг «-n» подавляет вывод (происходящий по умолчанию). «script» состоит из команд редактирования, по одной в строке, имеющих формат:
«sed» циклически преобразует входные строки в выходные.
Адреса «[ addr [ , addr ] ]» — это либо номера строк, либо последняя строка (символ «$»), либо регулярные выражения в стиле редактора «ed»:
- «\» используется в многострочных командах для экранирования продолжения строки.
- «.» совпадает с любым символом.
- Если адреса не указаны — просматриваются все входные строки.
- Если один адрес, то выбираются совпадающие строки.
- Если заданы два адреса, выбираются строки в заданном интервале.
- «!cmd» выполняется команда «cmd», для строк, которые не были выбраны по адресам.
Для следующих (основных) функций (команд) максимальное число допустимых адресов указано в скобках.
(1)a\ text Добавляет text после указанной строки
Команда: Результат: Пример: Результат:
(2)b label Осуществляет переход к команде («cmd») «label:cmd». Если метка («label») отсутствует, то переход на конец командного файла.
(2)c\ text Удаляет выбранные строки и заменяет их на «text’.
(2)d Удаляет найденные строки
(1)i\ text Вставляет «text» на место выбранной строки. (сравните с «a\»)
(2)p Выводит найденные строки (используется с флагом «-n»).
(1)q Выходит из «sed».
(2)r rfile Читает файл «rfile» и выдает на выход.
(2)s/reg_expr/rpl/flags Заменяет регулярное выражение «reg_expr» на «rpl» с учетом флагов «flags»:
g | глобально (по всей строке) |
p | выводить замены |
w wfile | сохранять заменяемое в «wfile». |
Пример: Результат:
(2)y/str1/str2/ Заменяет все вхождения символов «str1» соответствующими символами «str2». Длины строк должны быть одинаковыми.
(2)! Cmd Команда(ы) «cmd» применяются к невыбранным строкам.
(1)= Выдает номера строк.
(2) Скобки группируют команды.
II. Язык обработки шаблонов awk
awk — команда контекстного поиска и преобразования текста. Она — фильтр. Ее можно рассматривать как оболочку «awk» в оболочке «shell».
1. Структура awk-программы
Программа состоит из операторов (правил), имеющих вид:
Частные случаи:
- <действие>— когда действие выполняется для всех строк.
- шаблон — когда выводятся строки с данным шаблоном.
Действие может состоять из последовательности операторов, разделяемой «;» или переводом строки или закрывающей скобкой.
Возможны комментарии (как в shell «#. «).
Пример:
Для дальнейших примеров возьмем входной файл «f-awk» ( фамилия инициалы год-приема-на-работу возраст ):
Иванов И.И. | 1980 | 50 |
Петров А.В. | 1979 | 40 |
Сидоров С.К. | 1979 | 40 |
Хведоров И.Х. | 1970 | 60 |
Существует два оператора специального вида («BEGIN»-начальные установки и «END» — «последействия»):
2. Вызов awk
Возможны два основных варианта:
Это простейший случай, когда программа (заключенная в кавычки » ‘ «) находится в теле команды, «-Fc» — флаг, меняющий стандартный разделитель полей на «c» «file» — имя файла исходных данных, при его отсутствии — со стандартного входа. (Этот формат использован в начальных примерах).
дают результат, аналогичный
Для демонстрации действия флага «-Fc» рассмотрим вызовы:
Первая команда «awk» выведет вторые поля (благодаря позиционной переменной «$2») строк, содержащие «до». (Кстати, позиционная переменная «$0» соответсвует всей строке). Во втором случае, благодаря флагу «-F» стандартные разделители заменены на символ «0», т.е. теперь выбранные строки воспринимаются, как разбитые на следующие поля:
Флаг «-f» говорит о том, что awk-программу надо брать из файла, имя которого указано следом (имя может быть произвольным и расширение «.awk» добавлено здесь просто из эстетических соображений).
3. awk-переменные и выражения
В языке awk выделяются две группы переменных: предопределенные и декларированные в программе. Исходные значения предопределенных переменных устанавливаются интерпретатором awk в процессе запуска и выполнения awk-программы.
К предопределенным относятся: | Умолчания: |
NR — номер текущей строки | |
NF — число полей в текущей строке | |
RS — разделитель строк на вводе | «\0» |
FS — разделитель полей на вводе | пробел и/или табуляция |
ORS — разделитель строк на выводе | RS |
OFS — разделитель полей на выводе | FS |
OFMT — формат вывода чиcл | «%.6g» |
FILENAME — имя входного файла. |
Прочим переменным пользователь может присваивать начальные значения. По умолчанию «0» или пустая строка (что здесь равнозначно!).
Типы переменных:
- позиционные,
- числа с плавающей точкой,
- строка символов,
- массив.
Интерпретатор awk рассматривает переменную как строковую, пока не возникает необходимость выполнить операции:
- если пробел (конкатенация), то строки;
- если «+», то числа с плавающей точкой.
Примеры: Результат: Результат:
Массив не об’является, а начинае существовать в момент первого использования. Индекс массива — любое ненулевое значение или строка. Массивы ассоциативные, т.е. не по вычисляемому индексу, а по совпадению содержания, например:
Массивы удобно использовать при суммированиях, например записи выплат имеют вид (файл «p-1»):
Результат (поименный нарастающий итог):
Операции как в Си | =, +=, -=, *=, /=, %=, +, /, %, ++, —. |
Сравнения чисел, если оба числа, иначе — строк | =, > |
Логические операции | !, ||, && |
Операция «пробел» | конкатенация. |
4. Примеры awk-программ
Значение позиционной переменной»пусто» (после окончания просмотра)
5. Селекторы
Здесь «селектор» следует понимать, как расширение понятия «шаблон», поскольку там где в структуре команды указан шаблон, в общем случае может стоять любой селектор.
Замечание. Открывающая скобка действия «<" должна быть в строке селектора.
В качестве селектора может быть:
- выражение;
- шаблон;
- их комбинация.
Соответствующие примеры: Пример:
3) Шаблон может формировать множество образцов или указывать, в каком месте поля искать:
/^a/ | поле начинается с «a» |
/a$/ | поле кончается «a» |
\+ | экранирует оператор |
[abc] | любой из символов «a», «b» и «c» |
[a-р] | любой символ диапазона |
* | 0 или больше вхождений регулярного выражения |
+ | 1 или больше вхождений регулярного выражения |
? | 0 или 1 вхождение регулярного выражения |
ab|cd | «ab» или «cd» |
Примеры сочетаний: Результат:
То есть в третьем поле выделить 70-е годы (7 и еще одна цифра от конца поля).
6. Еще примеры
7. Действия
В awk возможны следующие действия:
- присваивания выражений;
- операторы управления
- операторы вывода;
- встроенные функции.
Операторы управления
exit | завершить выполнение программы; |
next | перейти к следующей строке, управление на начало awk-программы; |
break | выход из цикла; |
continue | переход к следующей итерации; |
Структурные операторы
Структурные операторы в значительной степени аналогичны соответствующим операторам Си. В последнем случае для каждого индекса выполняется блок. Текстовые индексы рассматриваются в лексикографическом порядке.
Примеры Результат: Результат:
Здесь, кроме изменения очередности полей в строке на противоположное (что делает цикл «for»), предварительно устанавливается выходной разделитель — пробел и весь результат предварительно выдается в одну строку, поэтому после обработки каждой строки выдается команда «print RS» для перевода выходной строки. Редактор «sed» подключен через конвейер, чтобы убрать возможные пробелы в начале строки. Существенная деталь. Если запустить лишь базовую структуру
то все поля исходной таблицы с изменениями порядка внутри прежних строк получим вытянутыми в один столбец переводом строки:
Однако, если поставим «;» сразу после условия, т.е. сделаем пустое тело цикла, за пределы которого вынесен «print $k»
то получим исходную таблицу
поскольку «$k» после выхода из цикла будет иметь значение «0», а «$0» — соответсвует всей строке в качестве значения(!), то «print $k» будет после каждого цикла печатать полные строки.
8. Ввод и вывод данных
В общем случае в команде awk может быть указано несколько файлов. Напомним форматы вызова команды:
Файлы обрабатываются последовательно в указанном порядке. Это можно использовать для «настройки» awk команды при обработке последующих файлов.
Пусть файл «f0» имеет вид:
А файл awk-программы «prim.awk» имеет вид:
Тогда при вызове команды Результат:
То есть второе поле файла «f0» дает значение переменной «w1», а первое — «w2». Эти переменные используются в селекторах при обработке файла «f-awk».
Изменим программу в файле «f-awk»: Результат:
Если исключить первый оператор «next», то в выходном файле появится дополнительно первая строка:
поскольку выбирается снова первое поле в певом файле («f0»). Если исключить и второй «next», то в выходном файле появится дополнительно последняя строка:
которая ранее не выводилась, так как в предшествующий оператор » < print ("фамилия: "$1)>» заканчивал работу на ПОСЛЕДНЕЙ строке файла «f-awk», поэтому «next» пропускал последующую командную строку
И еще одна модификация в связи с вводом данных с терминала. Вызов команды будет:
А файл «prim.awk» примет вид:
9. Встроенные функции
sin (expr) | синус expr |
cos (expr) | косинус expr |
exp (expr) | возведение в степень expr |
log (expr) | натуральный логорифм expr |
sqrt (expr) | извлечение корня expr |
int (expr) | целая часть числа |
length (s) | длина строки s |
printf (fmt, . ) | форматирование (аналогично Си) по спецификации fmt. |
substr (s, m, n) | подстрока в n символов строки s, начинающаяся с m. |
getline () | чтение следующей строки. |
0 | конец файла, иначе 1. |
index (s1, s2) | номер позиции, с которой s1 совпадает с s2, иначе 0. |
split (s, M, c) | строка s разбивается элементы массива M по разделителю c (по умолчанию FS=» «); функция возвращает число полей. |
Здесь поля разделяются по «.», выбираются строки у которых длина первого поля больше 8-ми, и их длина «length ($1)» печатается перед строкой «$0». Результат: Результат:
Источник