Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метод_ПСРВ.doc
Скачиваний:
32
Добавлен:
12.02.2016
Размер:
1.6 Mб
Скачать

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

Примеры

awk ' $4~/40/ {if($3<=1980) {print("Фамилия: " $1 )

M["40"]++}}

$4~/50/ {M["50"]++}

END {for(i in M)

{print(" i =" i " M[" i "]=" M[i])}} ' f-awk

Результат:

Фамилия: Петров

Фамилия: Сидоров

i =40 M[40]=2

i =50 M[50]=1

2) awk ' BEGIN {ORS = " "}

{ for(k=NF; k>0; --k) {print $k}

{print RS}

} ' f-awk | sed 's/^ //'

Результат:

50 1980 И.И. Иванов

40 1979 А.В. Петров

40 1979 С.К. Сидоров

60 1970 И.Х. Хведоров

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

awk '{ for(k=NF; k>0; --k) {print $k}}' f-awk

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

50

1980

И.И.

Иванов

40

1979

А.В.

Петров

40

1979

С.К.

Сидоров

60

1970

И.Х.

Хведоров

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

awk '{ for(k=NF; k>0; --k); {print $k}}' f-awk

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

Иванов И.И. 1980 50

Петров А.В. 1979 40

Сидоров С.К. 1979 40

Хведоров И.Х. 1970 60

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

1.9. Ввод и вывод данных

В общем случае в команде 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)}