
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=" "); функция возвращает число полей. |
Примеры.
1) awk ' BEGIN {FS = "."; a=0}
length ($1) > 8 {print (length ($1), $0);
a++
}
END {print ("Найдено строк: " a) }' f-awk
Результат:
9 Сидоров С.К. 1979 40
10 Хведоров И.Х. 1970 60
Найдено строк: 2
Здесь поля разделяются по ".", выбираются строки у которых длина первого поля больше 8-ми, и их длина "length ($1)" печатается перед строкой "$0".
2) awk '{i=split($0, Name, ".");
for (j=1; j<=i; j++)
print ("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
3) awk '{print (length)}' f-awk
Результат:
22
22
22
22
Поскольку все строки были выровнены пробелами, а в длине строки учитываются все символы до конца строки.
4) awk '{printf "%7.2f %s\n", NR, $0}' f-awk
echo
awk '{printf "\t%s %s \n", NR, $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