Руководство пользователя для GNU Awk
5. Чтение входных файлов
5.4 Изменение содержимого поля
Вы можете изменять содержимое поля, прочтенное awk, внутри awk-программы; Эти изменения затрагивают только информацию, воспринятую программой как текущая входная запись. (Сам ввод остается неизменным, awk никогда не изменяет входной файл.)
Рассмотрим следующий пример и его результат:
$ awk '- $3 = $2 - 10;
print $2, $3 ""' inventory-shipped
a 13 3
a 15 5
a 15 5...
Знак `-' означает вычитание, так что эта программа изменяет поле три, $3, присваивая ему значение поля 2 минус десять, `$2 - 10'. (См. раздел 7.5 [Арифметические операции], стр. 82.) Затем поле два и новое значение для поля три печатаются.
Для того, чтобы все это работало, текст в поле $2 должен иметь смысл как число; цепочка символов должна быть превращена в число, над которым компьютер может произвести арифметические действия. Результат вычитания конвертируется опять в цепочку символов, которая становится полем три. См. раздел 7.4 [Конверсия цепочек и чисел], стр. 81.
Когда вы изменяете значение поля (воспринятого программой awk), текст входной записи пере вычисляется, чтобы содержать новое поле там, где было старое. Поэтому $0 изменяется соответственно измененным полям. Таким образом, программа печатает копию входного файла, в которой вторые поля в каждой записи уменьшены на 10.
$ awk '- $2 = $2 - 10;
print $0 ""' inventory-shipped
a Jan 3 25 15 115
a Feb 5 32 24 226
a Mar 5 24 34 228...
Вы можете также присваивать содержание полям,
выходящим за рамки записи.
Например,
$ awk '- $6 = ($5 + $4 + $3 + $2) ?
print $6 ""' inventory-shipped
a 168
a 297
a 301 ...
Мы создали $6, Значение которого есть сумма полей $2, $3, $4 и $5. Знак `+' представляет сложение. Для файла `inventory-shipped' $6 представляет общее количество пакетов, посланных морем в определенный месяц.
Создание нового поля изменяет внутреннюю копию текущей записи, сделанную awk-программой, т.е. значение $0. Так, если вы выполняете `print $0' после добавления поля, печатается запись с добавленным полем и с соответствующим количеством разделителей полей между ним и существовавшими ранее полями.
Такое пере вычисление зависит от NF и изменяет NF (количество полей; см. раздел 5.2 [Обследование полей], стр.40), и вследствие свойства, которое еще не рассматривалось, изменяет также разделитель выходных полей, OFS, который используется для разделения полей (см. раздел 6.3 [Выходные разделители], стр. 63). Например, NF присваивается значение номера старшего поля, которое вы создали.
Заметим вместе с тем, что одна только ссылка на поле вне рамок записи не изменяет значения ни $0 ни NF. Ссылка на поле вне записи производит только пустую цепочку.
Например,
if ($(NF+1) != "")
print "can't happen"
else print "everything is normal"
напечатает `everything is normal', потому что NF+1 конечно выходит за рамки. (См. раздел 9.1 [Оператор if-else], стр. 105, описывающий подробно операторы if-else. См. раздел 7.10 [Печать переменных и выражения сравнения], стр. 88, с подробной информацией об операторе `!='.)
Важно заметить, что присваивание значения существующему полю изменяет значение $0, но не меняет значение NF, даже если вы присваиваете пустую цепочку полю.
Например:
$ echo a b c d -- awk '- OFS = ":";
$2 = "" ? print
$0; print NF ""'
a a::c:d
a 4
Поле все еще там; оно только имеет пустое значение. Это видно вследствие двух двоеточий подряд. Следующий пример показывает, что происходит, когда создается новое поле.
$ echo a b c d -- awk '- OFS = ":";
$2 = "";
$6 = "new" ?
print $0;
print NF ""'
a a::c:d::new
a 6
Создается вставленное поле $5 с пустым значением (оно показано второй парой соседних двоеточий, а NF получает значение шесть. Уменьшение NF привет к потере значений полей, номера которых больше значения NF, и к пере вычислению $0. Вот соответствующий пример:
$ echo a b c d e f -- ../gawk '- print "NF =", NF;
? NF = 3; print $0 ""'
a NF = 6
a a b c
Назад | Вперед
Содержание (общее) | Содержание раздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|