Что означает 0 внутри команды awk
Перейти к содержимому

Что означает 0 внутри команды awk

  • автор:

awk, переменная внутри awk

Помогите, пожалуйста разобраться с awk есть файл вида:

aaa 111 222 bbb 222 333 ccc ddd # fff eee 

Нужно в зависимости от первого слова, добавить шаблон в конец строки, если следующая строчка начинается с пробела или с решетки, то шаблон берется из предыдущей строки Чтобы хранить шаблон предыдущей строки сделал перменную temp, но она почему-то не отрабатывает, всегда пустая

#!/bin/bash awk ' < if($1=="aaa") < temp="template1"; print $0 "DELIMETER'$temp'"; >else if($1=="bbb") < temp="template2"; print $0"DELIMETER'$temp'"; >else if(substr($0,1,1)==" " || $1 =="#") < print $0"DELIMETER'$temp'"; >else < print; >>' file 

Serg0087
11.09.20 15:58:57 MSK

Команда awk – примеры использования в Linux и Unix

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

Что это за команда awk?

AWK – это скриптовый язык, который полезен при работе в командной строке и широко применяется для обработки текста.

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

Базовый синтаксис awk

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

Выглядеть она может так:

awk '' your_file_name.txt

Когда вам нужно найти текст, соответствующий конкретному шаблону, или же конкретное слово в тексте, команда принимает следующий вид:

awk '/regex pattern/' your_file_name.txt

Создание образца файла

Для создания файла в командной строке используется команда touch . Например: touch filename.txt , где filename – это произвольное имя файла.

Затем можно с помощью команды open ( open filename.txt ) запустить обработчик текста вроде TextEdit, который позволит внести в файл нужное содержимое.

Предположим, у вас есть текстовый файл information.txt, содержащий данные, разделённые по столбцам.

Выглядеть этот файл может так:

firstName lastName age city ID Thomas Shelby 30 Rio 400 Omega Night 45 Ontario 600 Wood Tinker 54 Lisbon N/A Giorgos Georgiou 35 London 300 Timmy Turner 32 Berlin N/A

В приведённом примере мы видим по одному столбцу для
firstName , lastName , age , city и ID .

В любой момент можно просмотреть вывод содержимого вашего файла, выполнив cat text_file , где text_file представляет имя файла.

Вывод всего содержимого файла

Для вывода всего содержимого файла в качестве действия в фигурных скобках нужно указать print $0 .

Сработает эта команда аналогично ранее упомянутой cat .

awk '' information.txt
firstName lastName age city ID Thomas Shelby 30 Rio 400 Omega Night 45 Ontario 600 Wood Tinker 54 Lisbon N/A Giorgos Georgiou 35 London 300 Timmy Turner 32 Berlin N/A

Если захотите добавить нумерацию строк, то нужно будет дополнить действие переменной NR :

awk '' information.txt
1 firstName lastName age city ID 2 3 Thomas Shelby 30 Rio 400 4 Omega Night 45 Ontario 600 5 Wood Tinker 54 Lisbon N/A 6 Giorgos Georgiou 35 London 300 7 Timmy Turner 32 Berlin N/A

Вывод конкретных столбцов

При использовании awk можно указывать для вывода конкретные столбцы.

Вывод первого производится следующей командой:

awk '' information.txt
Thomas Omega Wood Giorgos Timmy

Здесь $1 означает первое поле, то есть в данном случае первый столбец.

Для вывода второго столбца используется $2 :

awk '' information.txt
lastName Shelby Night Tinker Georgiou Turner

По умолчанию начало и конец каждого столбца awk определяет по пробелу.

Для вывода большего числа столбцов, например, первого и четвёртого, нужно выполнить:

awk '' information.txt
firstName city Thomas Rio Omega Ontario Wood Lisbon Giorgos London Timmy Berlin

Здесь $1 представляет первое поле ввода (первый столбец), а $4 четвёртое. При этом они отделяются запятой, чтобы вывод разделялся пробелом и был более читаемым.

Для вывода последнего поля (последнего столбца) также можно использовать команду $NF , представляющую последнее поле записи:

awk '' information.txt
ID 400 600 N/A 300 N/A

Вывод конкретных строк столбца

Также можно указывать для вывода строку определённого столбца:

awk '' information.txt | head -1
FirstName

Разделим эту команду на две части. Сначала awk » information.txt выводит первый столбец. Затем её результат (который мы видели выше) с помощью символа | передаётся на обработку команде head , где аргумент -1 указывает на выбор первой строки столбца.

Для вывода двух строк команда будет такой:

awk '' information.txt | head -2
FirstName Dionysia

Вывод строк с заданным шаблоном

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

awk '/^O/' information.txt
Omega Night 45 Ontario 600

Эта команда выбирает все строки с текстом, начинающимся на O .

Действие команды начинается с символа ^ , который указывает на начало строки. После этого прописывается буква, с которой нужная вам строка должна начинаться.

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

awk '/0$/' information.txt
Thomas Shelby 30 Rio 400 Omega Night 45 Ontario 600 Giorgos Georgiou 35 London 300

Эта команда выводит строки, оканчивающиеся на 0 – здесь с помощью символа $ мы указываем, как должна заканчиваться нужная строка.

При этом её можно несколько изменить:

awk '! /0$/' information.txt 

Символ ! используется в качестве приставки «НЕ», а значит, в этом случае будут выбраны строки, которые не оканчиваются на 0 .

firstName lastName age city ID Wood Tinker 54 Lisbon N/A Timmy Turner 32 Berlin N/A 

Использование регулярных выражений

Для вывода слов, содержащих определённые буквы, а также слов, соответствующих указанному шаблону, мы снова используем прямые слэши.

К примеру, если нас интересуют слова, содержащие io , мы пишем:

awk ' /io/' information.txt
Thomas Shelby 30 Rio 400 Omega Night 45 Ontario 600 Giorgos Georgiou 35 London 300

Мы получили строки, в которых содержатся слова, содержащие io .

Теперь предположим, что в файле есть дополнительный столбец department :

firstName lastName age city ID department Thomas Shelby 30 Rio 400 IT Omega Night 45 Ontario 600 Design Wood Tinker 54 Lisbon N/A IT Giorgos Georgiou 35 London 300 Data Timmy Turner 32 Berlin N/A Engineering

Для поиска всей информации о людях, работающих в IT , нужно указать искомую строку между // :

awk '/IT/' information.txt
Thomas Shelby 30 Rio 400 IT Wood Tinker 54 Lisbon N/A IT

А что, если мы хотим увидеть только имена и фамилии сотрудников из IT ?

Тогда можно указать столбец так:

awk '/IT/' information.txt
Thomas Shelby Wood Tinker

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

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

awk '/N\/A$/' information.txt
Wood Tinker 54 Lisbon N/A Timmy Turner 32 Berlin N/A

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

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

Если вы, предположим, захотите найти всю информацию о сотрудниках в возрасте до 40 лет, то нужно будет использовать оператор сравнения < так:

awk '$3 < 40 < print $0 >' information.txt
Thomas Shelby 30 Rio 400 Giorgos Georgiou 35 London 300 Timmy Turner 32 Berlin N/A

В выводе представлена информация о людях моложе 40.

Заключение

Вот и всё. Теперь у вас есть необходимая основа для начала работы с awk и управления текстовыми данными.

Благодарю за чтение и успехов вам в обучении!

  • ruvds_перевод
  • awk. linux
  • Блог компании RUVDS.com
  • Настройка Linux
  • Системное администрирование
  • *nix

Что означает 0 внутри команды awk

awk — команда контекстного поиска и преобразования текста. Она — фильтр. Ее можно рассматривать как оболочку awk в оболочке shell .

1. СТРУКТУРА awk -ПРОГРАММЫ

Программа состоит из операторов (правил), имеющих вид:

шаблон шаблон . . . 

— когда действие выполняется для всех строк.
шаблон — когда выводятся строки с данным шаблоном.
Действие может состоять из последовательности операторов, разделяемой «;» или переводом строки или закрывающей скобкой.
Возможны комментарии (как в shell » #. «).
Пример:
Для дальнейших примеров возьмем входной файл » f-awk » ( фамилия инициалы год-приема-на-работу возраст ):

Иванов И.И. 1980 50 Петров А.В. 1979 40 Сидоров С.К. 1979 40 Хведоров И.Х. 1970 60 
awk '' f-awk # выдает весь текст; echo awk '/до/ ' f-awk # выдает строки, где есть "до". echo awk '/до/ <>' f-awk # выдает строки, где есть "до" echo awk '/до/ ' f-awk 
Иванов И.И. 1980 50 Петров А.В. 1979 40 Сидоров С.К. 1979 40 Хведоров И.Х. 1970 60 Сидоров С.К. 1979 40 Хведоров И.Х. 1970 60 Сидоров С.К. 1979 40 Хведоров И.Х. 1970 60 Привет! Привет! 

Существует два оператора специального вида (» BEGIN «-начальные установки и » END » — «последействия»):

BEGIN шаблон шаблон . . . END 
2. ВЫЗОВ awk

Возможны два основных варианта:

awk [-Fc] 'prog.awk' [files] 

Это простейший случай, когда программа (заключенная в кавычки » ‘ «) находится в теле команды,
-Fc — флаг, меняющий стандартный разделитель полей на » c »
file — имя файла исходных данных, при его отсутствии — со стандартного входа. (Этот формат использован в начальных примерах).

cat f-awk | awk '/до/ ' 
awk '/до/ ' < f-awk 

дают результат, аналогичный

awk '/до/ ' f-awk 

Для демонстрации действия флага » -Fc » рассмотрим вызовы:

 awk '/до/ $2)>' f-awk awk -F0 '/до/ $2)>' f-awk 

На экран будет выведено:

С.К. И.Х. 6 

Первая команда awk выведет вторые поля (благодаря позиционной переменной » $2 «) строк, содержащие «до». (Кстати, позиционная переменная » $0 » соответсвует всей строке).
Во втором случае, благодаря флагу » -F » стандартные разделители заменены на символ » 0 «, т.е. теперь выбранные строки воспринимаются, как разбитые на следующие поля:

Сидоров С.К. 1979 40 ---------------------^-------------------- 1-е поле 2-е поле (пусто) Хведоров И.Х. 1970 60 -----------------^---^-------------------- 1-е поле 23-е поле (пусто) 
awk [-Fc] -f prog.awk [files] 

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

3. awk-ПЕРЕМЕННЫЕ И ВЫРАЖЕНИЯ

В языке awk выделяются две группы переменных:
предопределенные и декларированные в программе. Исходные значения предопределенных переменных устанавливаются интерпретатором awk в процессе запуска и выполнения awk -программы.
К предопределенным относятся: Умолчания:
NR номер текущей строки;
NF число полей в текущей строке;
RS разделитель строк на вводе; » \0 »
FS разделитель полей на вводе; пробел и/или табуляция
ORS разделитель строк на выводе; RS
OFS разделитель полей на выводе; FS
OFMT формат вывода чиcл; » %.6g »
FILENAME имя входного файла.

Прочим переменным пользователь может присваивать начальные значения. По умолчанию » 0 » или пустая строка (что здесь равнозначно!).
Типы переменных:
— позиционные,
— числа с плавающей точкой,
— строка символов,
— массив.

Интерпретатор awk рассматривает переменную как строковую, пока не возникает необходимость выполнить операции:
— если пробел (конкатенация), то строки;
— если » + «, то числа с плавающей точкой.

awk '$3 $4; print a>' f-awk awk '$3+$4; print a>' f-awk 
198050 197940 197940 197060 2030 2019 2019 2030 
awk '<> END 2 + 2 ; print a>' < f-awk awk '<> END 2 + "2" ; print a>' < f-awk awk '<> END 2 + "два" ; print a>' < f-awk awk '<> END print a>' < f-awk awk '<> END 2.2 + 2.000 ; print a>' < f-awk 
4 4 2 0 4.2 

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

 day [Jan][31] = Mon day [Feb][01] = Tue day [Feb][02] = Wed 

Массивы удобно использовать при суммированиях, например записи выплат имеют вид (файл » p-1 «):

John 100 Mary 200 Mary 200 John 100 John 300 
awk '$1] += $2; print $1 sum[$1]> ' < p-1 

Результат (поименный нарастающий итог):

John100 Mary200 Mary400 John200 John500 

Сравнения чисел, если оба числа, иначе — строк:
< , = , >

Операция «пробел» — конкатенация.

4. ПРИМЕРЫ awk -ПРОГРАММ
awk '$2, $3)>' f-awk 
И.И. 1980 А.В. 1979 С.К. 1979 И.Х. 1970 
awk '/е/ $2, $3)>' f-awk 
А.В. 1979 И.Х. 1970 
awk '/е/ $1, 2000 - $3)>' f-awk 
Петров 21 Хведоров 30 
awk '< s = s + $4> END print ("Средний возраст:" s/NR)>' f-awk 
Суммарный возраст:190 Средний возраст:47.5 
awk '< s += $4 > END print ("Значение позиционной переменной" $4 "\"пусто\" \ после окончания просмотра)") print ("Суммарный возраст:" s) print ("Средний возраст:" s/NR)>' f-awk 
NR=1 NF=4 NR=2 NF=4 NR=3 NF=4 NR=4 NF=4 FILENAME=f-awk 

Значение позиционной переменной «пусто» после окончания просмотра)

Суммарный возраст:190 Средний возраст:47.5 
5. СЕЛЕКТОРЫ

Здесь «селектор» следует понимать, как расширение понятия «шаблон», поскольку там где в структуре команды указан шаблон, в общем случае может стоять любой селектор.
ЗАМЕЧАНИЕ. Открывающая скобка действия » < " должна быть в строке селектора.
В качестве селектора может быть:
1) выражение;
2) шаблон;
3) их комбинация.

Соответсвующие примеры:
1)

$3 != $4 && $3 > 1970 $3 % 2 == 1 $1=="Иванов" - кавычки, чтобы воспринималось, как строка. 
/ab/ отлично от /a b/, / ab/ и /ab / Nполя ^шаблон - по совпадению Nполя !^шаблон - по несовпадению 
awk '$3~0 ' < f-awk echo awk '$3!~0 ' < f-awk 
Иванов И.И. 1980 50 Хведоров И.Х. 1970 60 Петров А.В. 1979 40 Сидоров С.К. 1979 40 

3) Шаблон может формировать множество образцов или указывать, в каком месте поля искать:
/^a/ — поле начинается с » a »
/a$/ — поле кончается » a »
\+ — экранирует оператор
[abc] — любой из символов » a «, » b » и » c »
[a-р] — любой символ диапазона
* — 0 или больше вхождений регулярного выражения
+ — 1 или больше вхождений регулярного выражения
? — 0 или 1 вхождение регулярного выражения
ab|cd — » ab » или » cd «

awk ' $3~/(7[0-9])$/ ' f-awk 
Петров А.В. 1979 40 Сидоров С.К. 1979 40 Хведоров И.Х. 1970 60 

То есть в третьем поле выделить 70-е годы (7 и еще одна цифра от конца поля).

6. ЕЩЕ ПРИМЕРЫ
awk '$1=="Иванов" ' f-awk 
Иванов И.И. 1980 50 
awk '$4/2==30 ' f-awk 
Хведоров И.Х. 1970 60 
awk '$3 != $4 && $3 > 1970 ' f-awk 
Иванов И.И. 1980 50 Петров А.В. 1979 40 Сидоров С.К. 1979 40 
awk '$1~/нов$/ ' f-awk 
Иванов И.И. 1980 50 
awk '/^Ив|дор/ ' f-awk 
Иванов И.И. 1980 50 Сидоров С.К. 1979 40 Хведоров И.Х. 1970 60 
awk '/1980/,/1979/ ' f-awk 
Иванов И.И. 1980 50 Петров А.В. 1979 40 
7. ДЕЙСТВИЯ

В awk возможны следующие действия:
1) присваивания выражений;
2) операторы управления
3) операторы вывода;
4) встроенные функции.

ОПЕРАТОРЫ УПРАВЛЕНИЯ

exit — завершить выполнение программы;
next — перейти к следующей строке, управление на начало awk-программы;
break — выход из цикла;
continue — переход к следующей итерации;

if (условие) [else ] while (условие) for (выражение; условие; выражение) for (индекс in имя_массива)

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

awk ' $4~/40/ $31980) $1 ) M["40"]++>> $4~/50/ 50"]++> END in M) 40 M[40]=2 i =50 M[50]=1 
awk ' BEGIN < for(k=NF; k>0; --k) $k> > ' f-awk | sed 's/^ //' 
50 1980 И.И. Иванов 40 1979 А.В. Петров 40 1979 С.К. Сидоров 60 1970 И.Х. Хведоров 

Здесь, кроме изменения очередности полей в строке на противоположное (что делает цикл » for «), предварительно устанавливается выходной разделитель — пробел и весь результат предварительно выдается в одну строку, поэтому после обработки каждой строки выдается команда » print RS » для перевода выходной строки. Редактор sed подключен через конвейер, чтобы убрать возможные пробелы в начале строки.
Существенная деталь. Если запустить лишь базовую структуру

awk '< for(k=NF; k>0; --k) $k>>' f-awk 

то все поля исходной таблицы с изменениями порядка внутри прежних строк получим вытянутыми в один столбец переводом строки:

50 1980 И.И. Иванов 40 1979 А.В. Петров 40 1979 С.К. Сидоров 60 1970 И.Х. Хведоров 

Однако, если поставим » ; » сразу после условия, т.е. сделаем пустое тело цикла, за пределы которого вынесен » print $k »

awk '< for(k=NF; k>0; --k); $k>>' f-awk 

то получим исходную таблицу

Иванов И.И. 1980 50 Петров А.В. 1979 40 Сидоров С.К. 1979 40 Хведоров И.Х. 1970 60 

поскольку » $k » после выхода из цикла будет иметь значение » 0 «, а » $0 » — соответсвует всей строке в качестве значения( ! ), то » print $k » будет после каждого цикла печатать полные строки.

8. ВВОД И ВЫВОД ДАННЫХ

В общем случае в команде awk может быть указано несколько файлов.
Напомним форматы вызова команды:

awk [-Fc] 'prog.awk' [file . ] awk [-Fc] -f prog.awk [file . ] ^ 

Файлы обрабатываются последовательно в указанном порядке.
Это можно использовать для «настройки» awk команды при обработке последующих файлов.

Пусть файл » f0 » имеет вид:

60 Сидоров 

А файл awk -программы » prim.awk » имеет вид:

FILENAME == "f0" < # если просматривается файл "f0" w1 = $2 # присваиваются значения переменным w2 = $1 # w1 - Сидоров, w2 - 60 > $1 == w1 < print ("фамилия: "$1)> # означенные переменные $4 == w2 < print ("годы: " $4)> # используются в # селекторах 

Тогда при вызове команды

awk -f prim.awk f0 f-awk 
фамилия: Сидоров годы: 60 

То есть второе поле файла » f0 » дает значение переменной » w1 «, а первое — » w2 «. Эти переменные используются в селекторах при обработке файла » f-awk «.

Изменим программу в файле » f-awk «:

FILENAME == "f0" < w1 = $2 w2 = $1 next > < print ("фамилия: "$1); next> $4 == w2 < print ("годы: " $4)> 
фамилия: Иванов фамилия: Петров фамилия: Сидоров фамилия: Хведоров 

Если исключить первый оператор » next «, то в выходном файле появится дополнительно первая строка:

фамилия: 60 

поскольку выбирается снова первое поле в певом файле (» f0 «).
Если исключить и второй » next «, то в выходном файле появится дополнительно последняя строка:

годы: 60 

которая ранее не выводилась, так как в предшествующий оператор » < print ("фамилия: "$1)>» заканчивал работу на последней строке файла » f-awk «, поэтому » next » пропускал последующую командную строку

$4 == w2 < print ("годы: " $4)> 

И еще одна модификация в связи с вводом данных с терминала. Вызов команды будет:

awk -f prim.awk f0 f-awk 

А файл » prim.awk » примет вид:

BEGIN < print ("Введите годы и фамилию: ")> FILENAME == "-" < w1 = $2 w2 = $1 next > $1 == w1 < print ("фамилия: "$1); next> $4 == w2 < print ("годы: " $4)> 
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=» » ); функция возвращает число полей.

awk ' BEGIN length ($1) > 8 $1), $0); a++ > END ' f-awk 
9 Сидоров С.К. 1979 40 10 Хведоров И.Х. 1970 60 Найдено строк: 2 

Здест поля разделяются по » . «, выбираются строки у которых длина первого поля больше 8-ми, и их длина » length ($1) » печатается перед строкой » $0 «.

awk '$0, Name, "."); for (j=1; jprint ("Name[" j "]=" Name[j]) >' f-awk 
Name[1]=Иванов И Name[2]=И Name[3]= 1980 50 Name[1]=Петров А Name[2]=В Name[3]= 1979 40 Name[1]=Сидоров С Name[2]=К Name[3]= 1979 40 Name[1]=Хведоров И Name[2]=Х Name[3]= 1970 60 
awk '' f-awk 
22 22 22 22 

Поскольку все строки были выровнены пробелами, а в длине строки учитываются все символы до конца строки.

awk '$0>' f-awk echo awk '$0>' f-awk 
 1.00 Иванов И.И. 1980 50 2.00 Петров А.В. 1979 40 3.00 Сидоров С.К. 1979 40 4.00 Хведоров И.Х. 1970 60 1 Иванов И.И. 1980 50 2 Петров А.В. 1979 40 3 Сидоров С.К. 1979 40 4 Хведоров И.Х. 1970 60 

(Aho, Weinberg, Kernigan)


2014-07-27, lissyara
gmirror
Удалённое создание софтверного зеркала средствами gmirror, на диске разбитом с использованием gpart. Использование меток дисков для монтирования разделов. 2013-08-20, zentarim
Scan+Print server FreeBSD 9
Настройка сервера печати и сервера сканирования под управлением операционной системы FreebSD 9 для МФУ Canon PIXMA MP540 2011-11-20, BlackCat
Разъём на WiFi-карту
Делаем съёмной несъёмную антену на WiFi-карте путём установки ВЧ-разъёма 2011-09-14, manefesto
Настройка git+gitosis
Настройка системы контроля версия исходного кода в связке git+gitosis+ssh 2011-08-14, zentarim
Wi-FI роутер + DHCP + DNS
Настройка Wi-Fi роутера на Freebsd 8 + DNS сервер + DHCP сервер: чтобы Wi-Fi клиенты были в одной подсети с проводными, проводные и беспроводные клиенты получали адреса автоматически по DHCP, кэширующ 2011-06-15, -ZG-
Охранная система на FreeBSD+LPT
В этой статье описана попытка реализации простой охранной системы на базе FreeBSD с подключением к ней охранных устройтсв на LPT порт и видеорегистрацией. 2011-03-13, terminus
ng_nat
Описание работы ng_nat, практическое использование, достоинства и недостатки в сравнении с ipfw nat 2011-02-20, Капитан
Nagios+Digitemp
Статья описывает создание системы оповещения о превышении температуры в специальных помещениях на основе Nagios с использованием программы Digitemp. 2011-02-17, Le1
Zyxel Configuration
Скрипт для массового изменения конфига свичей Zyxel. Берет из файла iplist список ip-шек, заходит последовательно на каждый и выполняет комманды из файла commands, записывая происходящее в лог файл. 2011-02-16, fox
hast carp zfs ucarp cluster
HAST (Highly Available Storage), CARP, UCARP, ZFS, Cluster настройка и одаптация плюс личные размышления… 2011-02-04, BlackCat
Восстановление ZFS
История о том, как был восстановлен развалившийся RAIDZ ZFS-пул (перешедший в FAULTED) с помощью скотча и подручных средств. Или о том, какие приключения ожидают тех, кто не делает резервных копий. 2011-02-03, Капитан
1-Wire
Статья описывает самостоятельное изготовление контроллера DS9097 для съёма показаний с датчиков температуры DS1820 с помощью программы Digitemp. 2011-01-28, Капитан
Температура в серверной
Статья описывает построение системы наблюдения за температурой в помещении серверной с использованием программы Digitemp и выводом графиков в MRTG 2011-01-21, m4rkell
Syslog server
Как то буквально на днях, у нас завалилось, что то в еве) или не в еве не суть. Суть в том, что когда захотели снять логи с хостов esx обнаружили, что хранят эти негодяи логии только за последнии сутк 2011-01-07, lissyara
Canon/gphotofs
Монтирование цифровых фотоаппаратов Canon (PTP) как файловой системы, автоматизация этого процесса через события devd и внешние скрипты. 2010-12-13, Al
IPSec
Описание принципов работы IPSEC и способов аутентификации. 2010-12-07, manefesto
FreeBSD on flash
Было принято решении переехать на USB Flash и установить минимальный джентельменский набор для работы своего роутера. Делаем =) 2010-12-05, Fomalhaut
root ZFS, GPT
Инструкция по установке FreeBSD с использованием в качестве таблицы разделов GPT и в качестве основной файловой системы — ZFS 2010-09-05, Cancer
Настройка аудиоплеера на ximp3
Цели: Простенький аудиоплеер, для того что бы тетя продавец в магазине утром пришла нажала на кнопку Power и заиграла в зале музыка, так же был доступ по сети, общая шара куда можно заливать музыку, к 2010-08-31, Cancer
Установка и настройка OpenVPN
На днях появилась задача — объединить головной офис и 3 филиала в одну сеть через интернет посредством OpenVPN, чтобы люди могли подключаться через RDP к базам 1С на серверах. 2010-08-25, manefesto
freebsd lvm
Использование linux_lvm для работы с LVM разделами из-под FreeBSD. Проблемы которые возники при монтирование lvm раздела 2010-04-30, gonzo111
proftpd file auth&quota
Proftpd — квоты и авторизация из файлов, без использования базы данных и/или системных пользователей 2010-04-22, lissyara
tw_cli
Пошаговая инструкция по восстановлению RAID на контроллере 3ware, из которого выпал один диск. Настройка мониторинга состояния рейда и отчётов о его состоянии на email. 2010-04-14, fox
MySQL Master+Master
MySQL (Master Master) and (Master Slave) Как настроить репликацию… 2010-03-09, terminus
DNS zones
Краткий ликбез про управление DNS зонами. Примеры проведения делегирования прямых и обратных DNS зон. 2010-03-09, aspera
Squid+AD (group access)
Настройка прокси сервера SQUID с автроризацией пользователей в AD. Разделение пользователей на группы 2010-03-02, BlackCat
Шлюз: Часть 4
Настройка дополнительных сервисов: синхронизация времени (OpenNTPD), клиент DynDNS.org. 2010-03-01, BlackCat
Шлюз: Часть 3
Настройка DHCP и DNS серверов для работы внутри частной сети, c поддержкой внутренних (частных зон) DNS, а так же интеграция DHCP и DNS сервисов. 2010-03-01, BlackCat
Шлюз: Часть 2
Конфигурация МСЭ pf для проброса портов с изменением порта назначения и без, а так же поддержки активного режима FTP и ограничения максимального размера сегмента 2010-03-01, BlackCat
Шлюз: Часть 1
Быстрая настройка шлюза/маршрутизатора с установлением PPPoE-соединения, поддержкой NAT и DNS-forwarding. 2010-02-23, Morty
darkstat
Простая считалка траффика, со встроенным веб-сервером. Очень маленькая, может делать отчеты трафика по хостам, портам, протоколам, а также строить графики 2010-01-23, gonzo111
squid+sams+sqstat
Пилим squid и sams — примеры конфигов с объяснениями. Установка SqStat. 2009-12-19, schizoid
mpd5 + radius + ng_car + Abills
Настройка pppoe-сервера с биллинговой системой Abills и шейпером ng_car 2009-11-16, lissyara
UFS->ZFS
Удалённая миграция с UFS на ZFS. Загрузка с раздела zfs. Настройка для работы с малым количеством памяти под архитектурой i386. 2009-11-13, gx_ua
fusefs-ntfs
Установка, настройка и использование fusefs-ntfs, драйвер NTFS, предназанченного для монтирования NTFS разделов под FreeBSD 2009-11-12, Morty
LiveCD
Создание собственного LiveCD с необходимыми вам изменениями, автоматизирование данного процесса, а так же вариант скоростной сборки СД. 2009-09-27, lissyara
Samba как PDC
Контроллер домена — аналог M$ NT4 домена под самбой, без использования LDAP и прочей хиромантии. Просто и быстро =) 2009-08-30, terminus
ipfw nat
Подробное руководство по ipfw nat, сложные случаи конфигурации. 2009-08-24, levantuev
HotSpot
Установка Hotspot системы в общественное заведение. 2009-08-18, lissyara
diskless
Создание бездисковых терминалов под управлением FreeBSD — с загрузкой по сети. Используются для старта rdesktop и подключения к виндовому серверу терминалов. 2009-07-29, BAV_Lug
Видеонаблюдение
Настройка бюджетного варианта видеонаблюдения на удаленном объекте 2009-07-22, Cancer
OpenLDAP адресная книга
Настройка и создание адресной книги на базе OpenLDAP + phpLDAPadmin 2009-06-30, SergeySL
AimSniff
Руководство по созданию системы мониторинга ICQ-переписки на базе AimSniff, использующей базу данных MySQL для хранения и Web-интерфейс WAS (Web Aim Sniff) для просмотра перехваченных сообщений 2009-06-25, atrium
Управление правами доступа
Полномочия пользователей и файлов, принадлежащих им, формирует концепцию ОС UNIX. 2009-06-16, DNK
Exim+PgSQL
Установка почтовой системы exim+pgsql на FreeBSD 7.1 2009-05-30, mvalery
HDD(mbr) -> HDD(gpt)
Как разбить диск размером более 2TB на разделы, сделать загрузочным, а затем перенести на него информацию с рабочей системы — донора. 2009-05-22, Cancer
SendXMPP
Отправка сообщений на Джаббер сервер по средствам SendXMPP 2009-05-11, Raven2000
Network UPS Tools
Network UPS Tools представляет собой набор программ, которые обеспечивают общий интерфейс для мониторинга и администрирование UPS оборудования. 2009-04-29, m0ps
IPSEC over GRE with RIP
Пример IPSEC over GRE и динамическим роутингом (RIP), с ADSL в качестве последней мили на оборудовании Cisco. 2009-04-24, WhiteBear777
qemu network
Появилась необходимость поставить на БСД эмулятор(qemu) и настроить в качестве гостевой ОС Windows XP, предоставив ей выход в локалку и в сеть internet.
вверх

Статистика сайта
Сейчас на сайте находится: 4 чел.
За последние 30 мин было: 22 человек
За сегодня было
333 показов,
64 уникальных IP

Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Bash-скрипты, часть 8: язык обработки данных awk

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

Утилита awk, или точнее GNU awk, в сравнении с sed, выводит обработку потоков данных на более высокий уровень. Благодаря awk в нашем распоряжении оказывается язык программирования, а не довольно скромный набор команд, отдаваемых редактору. С помощью языка программирования awk можно выполнять следующие действия:

  • Объявлять переменные для хранения данных.
  • Использовать арифметические и строковые операторы для работы с данными.
  • Использовать структурные элементы и управляющие конструкции языка, такие, как оператор if-then и циклы, что позволяет реализовать сложные алгоритмы обработки данных.
  • Создавать форматированные отчёты.

Особенности вызова awk

Схема вызова awk выглядит так:

$ awk options program file

Awk воспринимает поступающие к нему данные в виде набора записей. Записи представляют собой наборы полей. Упрощенно, если не учитывать возможности настройки awk и говорить о некоем вполне обычном тексте, строки которого разделены символами перевода строки, запись — это строка. Поле — это слово в строке.

Рассмотрим наиболее часто используемые ключи командной строки awk:

-F fs — позволяет указать символ-разделитель для полей в записи.
-f file — указывает имя файла, из которого нужно прочесть awk-скрипт.
-v var=value — позволяет объявить переменную и задать её значение по умолчанию, которое будет использовать awk.
-mf N — задаёт максимальное число полей для обработки в файле данных.
-mr N — задаёт максимальный размер записи в файле данных.
-W keyword — позволяет задать режим совместимости или уровень выдачи предупреждений awk.

Настоящая мощь awk скрывается в той части команды его вызова, которая помечена выше как program . Она указывает на файл awk-скрипта, написанный программистом и предназначенный для чтения данных, их обработки и вывода результатов.

Чтение awk-скриптов из командной строки

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

Запустим эту команду… И ничего не произойдёт Дело тут в том, что мы, при вызове awk, не указали файл с данными. В подобной ситуации awk ожидает поступления данных из STDIN. Поэтому выполнение такой команды не приводит к немедленно наблюдаемым эффектам, но это не значит, что awk не работает — он ждёт входных данных из STDIN .

Если теперь ввести что-нибудь в консоль и нажать Enter , awk обработает введённые данные с помощью скрипта, заданного при его запуске. Awk обрабатывает текст из потока ввода построчно, этим он похож на sed. В нашем случае awk ничего не делает с данными, он лишь, в ответ на каждую новую полученную им строку, выводит на экран текст, заданный в команде print .

Первый запуск awk, вывод на экран заданного текста

Что бы мы ни ввели, результат в данном случае будет одним и тем же — вывод текста.
Для того, чтобы завершить работу awk, нужно передать ему символ конца файла (EOF, End-of-File). Сделать это можно, воспользовавшись сочетанием клавиш CTRL + D .

Неудивительно, если этот первый пример показался вам не особо впечатляющим. Однако, самое интересное — впереди.

Позиционные переменные, хранящие данные полей

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

  • $0 — представляет всю строку текста (запись).
  • $1 — первое поле.
  • $2 — второе поле.
  • $n — n-ное поле.

Рассмотрим использование этих переменных на простом примере. А именно, обработаем файл, в котором содержится несколько строк (этот файл показан на рисунке ниже) с помощью такой команды:

$ awk '' myfile

Вывод в консоль первого поля каждой строки

Здесь использована переменная $1 , которая позволяет получить доступ к первому полю каждой строки и вывести его на экран.

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

$ awk -F: '' /etc/passwd

Указание символа-разделителя при вызове awk

Эта команда выводит первые элементы строк, содержащихся в файле /etc/passwd . Так как в этом файле в качестве разделителей используются двоеточия, именно этот символ был передан awk после ключа -F .

Использование нескольких команд

Вызов awk с одной командой обработки текста — подход очень ограниченный. Awk позволяет обрабатывать данные с использованием многострочных скриптов. Для того, чтобы передать awk многострочную команду при вызове его из консоли, нужно разделить её части точкой с запятой:

$ echo "My name is Tom" | awk ''

Вызов awk из командной строки с передачей ему многострочного скрипта

В данном примере первая команда записывает новое значение в переменную $4 , а вторая выводит на экран всю строку.

Чтение скрипта awk из файла

Awk позволяет хранить скрипты в файлах и ссылаться на них, используя ключ -f . Подготовим файл testfile , в который запишем следующее:

Вызовем awk, указав этот файл в качестве источника команд:

$ awk -F: -f testfile /etc/passwd

Вызов awk с указанием файла скрипта

Тут мы выводим из файла /etc/passwd имена пользователей, которые попадают в переменную $1 , и их домашние директории, которые попадают в $6 . Обратите внимание на то, что файл скрипта задают с помощью ключа -f , а разделитель полей, двоеточие в нашем случае, с помощью ключа -F .

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

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

Выполнение команд до начала обработки данных

Иногда нужно выполнить какие-то действия до того, как скрипт начнёт обработку записей из входного потока. Например — создать шапку отчёта или что-то подобное.

Для этого можно воспользоваться ключевым словом BEGIN . Команды, которые следуют за BEGIN , будут исполнены до начала обработки данных. В простейшем виде это выглядит так:

$ awk 'BEGIN '

А вот — немного более сложный пример:

$ awk 'BEGIN ' myfile

Выполнение команд до начала обработки данных

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

Выполнение команд после окончания обработки данных

Ключевое слово END позволяет задавать команды, которые надо выполнить после окончания обработки данных:

$ awk 'BEGIN  END ' myfile

Результаты работы скрипта, в котором имеются блоки BEGIN и END

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

BEGIN < print "The latest list of users and shells" print " UserName \t HomePath" print "-------- \t -------" FS=":" > < print $1 " \t " $6 >END

Тут, в блоке BEGIN , создаётся заголовок табличного отчёта. В этом же разделе мы указываем символ-разделитель. После окончания обработки файла, благодаря блоку END , система сообщит нам о том, что работа окончена.

$ awk -f myscript /etc/passwd

Обработка файла /etc/passwd с помощью awk-скрипта

Всё, о чём мы говорили выше — лишь малая часть возможностей awk. Продолжим освоение этого полезного инструмента.

Встроенные переменные: настройка процесса обработки данных

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

Мы уже рассматривали позиционные переменные — $1 , $2 , $3 , которые позволяют извлекать значения полей, работали мы и с некоторыми другими переменными. На самом деле, их довольно много. Вот некоторые из наиболее часто используемых:

FIELDWIDTHS — разделённый пробелами список чисел, определяющий точную ширину каждого поля данных с учётом разделителей полей.
FS — уже знакомая вам переменная, позволяющая задавать символ-разделитель полей.
RS — переменная, которая позволяет задавать символ-разделитель записей.
OFS — разделитель полей на выводе awk-скрипта.
ORS — разделитель записей на выводе awk-скрипта.

По умолчанию переменная OFS настроена на использование пробела. Её можно установить так, как нужно для целей вывода данных:

$ awk 'BEGIN ' /etc/passwd

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

Переменная FIELDWIDTHS позволяет читать записи без использования символа-разделителя полей.

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

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

Предположим, имеется файл testfile , содержащий такие данные:

1235.9652147.91 927-8.365217.27 36257.8157492.5

Известно, что внутренняя организация этих данных соответствует шаблону 3-5-2-5, то есть, первое поле имеет ширину 3 символа, второе — 5, и так далее. Вот скрипт, который позволит разобрать такие записи:

$ awk 'BEGIN' testfile

Использование переменной FIELDWIDTHS

Посмотрим на то, что выведет скрипт. Данные разобраны с учётом значения переменной FIELDWIDTHS , в результате числа и другие символы в строках разбиты в соответствии с заданной шириной полей.

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

Иногда случается так, что поля в потоке данных распределены по нескольким строкам. Например, пусть имеется такой файл с именем addresses :

Person Name 123 High Street (222) 466-1234 Another person 487 High Street (523) 643-8754

Если попытаться прочесть эти данные при условии, что FS и RS установлены в значения по умолчанию, awk сочтёт каждую новую строку отдельной записью и выделит поля, опираясь на пробелы. Это не то, что нам в данном случае нужно.

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

Кроме того, в данном примере понадобится записать в переменную RS пустую строку. Обратите внимание на то, что в файле блоки данных о разных людях разделены пустой строкой. В результате awk будет считать пустые строки разделителями записей. Вот как всё это сделать:

$ awk 'BEGIN ' addresses

Результаты настройки переменных RS и FS

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

Встроенные переменные: сведения о данных и об окружении

Помимо встроенных переменных, о которых мы уже говорили, существуют и другие, которые предоставляют сведения о данных и об окружении, в котором работает awk:

ARGC — количество аргументов командной строки.
ARGV — массив с аргументами командной строки.
ARGIND — индекс текущего обрабатываемого файла в массиве ARGV .
ENVIRON — ассоциативный массив с переменными окружения и их значениями.
ERRNO — код системной ошибки, которая может возникнуть при чтении или закрытии входных файлов.
FILENAME — имя входного файла с данными.
FNR — номер текущей записи в файле данных.
IGNORECASE — если эта переменная установлена в ненулевое значение, при обработке игнорируется регистр символов.
NF — общее число полей данных в текущей записи.
NR — общее число обработанных записей.

Переменные ARGC и ARGV позволяют работать с аргументами командной строки. При этом скрипт, переданный awk, не попадает в массив аргументов ARGV . Напишем такой скрипт:

$ awk 'BEGIN' myfile

После его запуска можно узнать, что общее число аргументов командной строки — 2, а под индексом 1 в массиве ARGV записано имя обрабатываемого файла. В элементе массива с индексом 0 в данном случае будет «awk».

Работа с параметрами командной строки

Переменная ENVIRON представляет собой ассоциативный массив с переменными среды. Опробуем её:

$ awk ' BEGIN< print ENVIRON["HOME"] print ENVIRON["PATH"] >'

Работа с переменными среды

Переменные среды можно использовать и без обращения к ENVIRON . Сделать это, например, можно так:

$ echo | awk -v home=$HOME ''

Работа с переменными среды без использования ENVIRON

Переменная NF позволяет обращаться к последнему полю данных в записи, не зная его точной позиции:

$ awk 'BEGIN ' /etc/passwd

Пример использования переменной NF

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

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

$ awk 'BEGIN

Исследование переменной FNR

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

Взглянем теперь на то, как ведёт себя в подобной ситуации переменная NR:

$ awk ' BEGIN  END' myfile myfile

Различие переменных NR и FNR

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

Пользовательские переменные

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

$ awk ' BEGIN< test="This is a test" print test >'

Работа с пользовательской переменной

Условный оператор

Awk поддерживает стандартный во многих языках программирования формат условного оператора if-then-else . Однострочный вариант оператора представляет собой ключевое слово if , за которым, в скобках, записывают проверяемое выражение, а затем — команду, которую нужно выполнить, если выражение истинно.

Например, есть такой файл с именем testfile :

10 15 6 33 45

Напишем скрипт, который выводит числа из этого файла, большие 20:

$ awk ' 20) print $1>' testfile

Однострочный оператор if

Если нужно выполнить в блоке if несколько операторов, их нужно заключить в фигурные скобки:

$ awk ' < if ($1 >20) < x = $1 * 2 print x >>' testfile

Выполнение нескольких команд в блоке if

Как уже было сказано, условный оператор awk может содержать блок else :

$ awk ' < if ($1 >20) < x = $1 * 2 print x >else < x = $1 / 2 print x >>' testfile

Условный оператор с блоком else

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

$ awk ' 20) print $1 * 2; else print $1 / 2>' testfile

Условный оператор, содержащий ветви if и else, записанный в одну строку

Цикл while

Цикл while позволяет перебирать наборы данных, проверяя условие, которое остановит цикл.

Вот файл myfile , обработку которого мы хотим организовать с помощью цикла:

124 127 130 112 142 135 175 158 245

Напишем такой скрипт:

$ awk ' < total = 0 i = 1 while (i < 4) < total += $i i++ >avg = total / 3 print "Average:",avg >' testfile

Обработка данных в цикле while

Цикл while перебирает поля каждой записи, накапливая их сумму в переменной total и увеличивая в каждой итерации на 1 переменную-счётчик i . Когда i достигнет 4, условие на входе в цикл окажется ложным и цикл завершится, после чего будут выполнены остальные команды — подсчёт среднего значения для числовых полей текущей записи и вывод найденного значения.

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

Вот как работает команда break :

$ awk ' < total = 0 i = 1 while (i < 4) < total += $i if (i == 2) break i++ >avg = total / 2 print "The average of the first two elements is:",avg >' testfile

Команда break в цикле while

Цикл for

Циклы for используются во множестве языков программировании. Поддерживает их и awk. Решим задачу расчёта среднего значения числовых полей с использованием такого цикла:

$ awk ' < total = 0 for (i = 1; i < 4; i++) < total += $i >avg = total / 3 print "Average:",avg >' testfile

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

Форматированный вывод данных

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

Спецификатор форматирования — это специальный символ, который задаёт тип выводимых данных и то, как именно их нужно выводить. Awk использует спецификаторы форматирования как указатели мест вставки данных из переменных, передаваемых printf .

Первый спецификатор соответствует первой переменной, второй спецификатор — второй, и так далее.

Спецификаторы форматирования записывают в таком виде:

%[modifier]control-letter

Вот некоторые из них:

c — воспринимает переданное ему число как код ASCII-символа и выводит этот символ.
d — выводит десятичное целое число.
i — то же самое, что и d .
e — выводит число в экспоненциальной форме.
f — выводит число с плавающей запятой.
g — выводит число либо в экспоненциальной записи, либо в формате с плавающей запятой, в зависимости от того, как получается короче.
o — выводит восьмеричное представление числа.
s — выводит текстовую строку.

Вот как форматировать выводимые данные с помощью printf :

$ awk 'BEGIN< x = 100 * 100 printf "The result is: %e\n", x >'

Форматирование выходных данных с помощью printf

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

Встроенные математические функции

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

cos(x) — косинус x ( x выражено в радианах).
sin(x) — синус x .
exp(x) — экспоненциальная функция.
int(x) — возвращает целую часть аргумента.
log(x) — натуральный логарифм.
rand() — возвращает случайное число с плавающей запятой в диапазоне 0 — 1.
sqrt(x) — квадратный корень из x .

Вот как пользоваться этими функциями:

$ awk 'BEGIN'

Работа с математическими функциями

Строковые функции

Awk поддерживает множество строковых функций. Все они устроены более или менее одинаково. Вот, например, функция toupper :

$ awk 'BEGIN'

Использование строковой функции toupper

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

Пользовательские функции

При необходимости вы можете создавать собственные функции awk. Такие функции можно использовать так же, как встроенные:

$ awk ' function myprint() < printf "The user %s has home path at %s\n", $1,$6 >BEGIN < myprint() >' /etc/passwd

Использование собственной функции

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

Итоги

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

Вы не могли не заметить, что многое из того, о чём мы говорим, не так уж и сложно для понимания, а зная основы, уже можно что-то автоматизировать, но если копнуть поглубже, вникнуть в документацию… Вот, например, The GNU Awk User’s Guide. В этом руководстве впечатляет уже одно то, что оно ведёт свою историю с 1989-го (первая версия awk, кстати, появилась в 1977-м). Однако, сейчас вы знаете об awk достаточно для того, чтобы не потеряться в официальной документации и познакомиться с ним настолько близко, насколько вам того хочется. В следующий раз, кстати, мы поговорим о регулярных выражениях. Без них невозможно заниматься серьёзной обработкой текстов в bash-скриптах с применением sed и awk.

Уважаемые читатели! Уверены, многие из вас периодически пользуются awk. Расскажите, как он помогает вам в работе?

  • Блог компании RUVDS.com
  • Настройка Linux
  • Системное администрирование

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *