Руководство пользователя для GNU Awk
5. Чтение входных файлов
5.6 Чтение данных фиксированной ширины
(В этом разделе обсуждается новая, экспериментальная возможность. Если вы еще неопытный пользователь awk, можете пропустить это при первом чтении.) В версии gawk 2.13 введено новое средство для действий с полями фиксированной ширины без распознавания разделителей полей. Данные этой природы появляются, например, на входе старых FORTRAN-программ, где числа примыкают друг к другу; или на выходе программ, которые не предусматривают их использования в качестве входа других программ. Примером последних может служить таблица, где все столбцы выпрямленным использованием переменного числа пробелов и пустые поля заполнены пробелами. Ясно, что принятое в awk нормальное разделение полей с помощью FS неудобно в этом случае. Хотя переносимые awk-программы могут использовать последовательность вызовов substr для $0 (см. раздел 12.3 [Встроенные функции для действий со строками], стр. 137), это громоздко и неэффективно при большом числе полей.
Разделение входной строки на поля фиксированной ширины указывается посредством присваивания цепочки, содержащей разделенные пробелами числа, встроенной переменной FIELDWIDTHS. Каждое число указывает ширину поля, включая столбцы между полями. Если нужно игнорировать колонки между полями, можно указывать ширину как отдельное поле, которое впоследствии игнорируется.
Следующие данные представляют выход утилиты Unix w. Они полезны для иллюстрации использования FIELDWIDTHS.
10:06pm up 21 days,
14:04, 23 users
User tty login idle JCPU PCPU what
hzuottyV0 8:58pm 9 5 vi p24.tex hzang ttyV3
6:37pm 50 -csh eklye ttyV5 9:53pm
7 1 em thes.tex dportein ttyV6 8:17pm
1:47 -csh gierd ttyD3 10:00pm 1 elm
dave ttyD4 9:47pm 4 4 w brent ttyp0
26Jun91 4:46 26:46 4:41 bash dave ttyq4
26Jun9115days 46 46 wnewmail
Следующая программа читает приведенный выше выход, переводит время простоя (idle time) в секунды и печатает первые два поля и вычисленное время простоя. (Это программа использует несколько средств awk, которые еще не рассматривались.)
BEGIN - FIELDWIDTHS = "9 6 10 6 7 7 35" "" NR ? 2 -
idle = $4 sub(/^ */, "", idle) # strip leading spaces if (idle == "")
idle = 0 if (idle ~ /:/) -
split(idle, t, ":") idle = t[1] * 60 + t[2] "" if (idle ~ /days/)
idle *= 24 * 60 * 60
print $1, $2, idle ""
Здесь приведен результат выполнения программы program на данных:
hzuo ttyV0 0 hzang ttyV3 50 eklye ttyV5 0
dportein ttyV6 107 gierd ttyD3 1
dave ttyD4 0 brent ttyp0 286
dave ttyq4 1296000
Другой (возможно, более практичный) пример входных данных фиксированной ширины представляет ввод колоды выборных карточек. В некоторых регионах США избиратели показывают свой выбор отверстиями в перфокартах. Затем эти карточки обрабатываются для подсчета голосов в пользу каждого кандидата или какого-нибудь определенного предпочтения.
Поскольку голосующий может не голосовать по некоторой альтернативе, любая колонка карты может быть пустой. awk-программа для обработки таких данных может использовать средство FIELDWIDTHS для упрощения чтения данных. (Конечно, получить gawk, которая работает на системе с чтением перфокарт, составляет отдельную задачу!)
Присваивание некоторого значения FS побуждает gawk вернуться к использованию FS для разделения полей. Используйте `FS = FS' для этого, не зная текущего значения FS.
Обсуждаемое средство еще экспериментально и может быть переработано со временем. Заметим в частности, что gawk не пытается проверить правильность значений, составляющих значение FIELDWIDTHS.
Назад | Вперед
Содержание (общее) | Содержание раздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|