Руководство пользователя для GNU Awk
5. Чтение входных файлов
5.7 Многострочные записи
В некоторых базах данных одна строка не может удобно содержать информацию одной записи. В таких случаях можно использовать многострочные записи. Первым шагом на этом пути должен быть выбор формата данных: если записи не определены как отдельные строки, как их определять? Что должно их разделять? Одна из возможностей состоит в выборе особого символа или строки для их разделения. Например, можно использовать прогон страницы (записываемый как `"f' в awk, аналогично тому как в Си), рассматривая каждую запись как страницу в файле. Чтобы сделать это, присвойте переменной RS значение ""f" (цепочка, содержащая символ конца страницы). Может также использоваться любой другой символ, не являющийся частью данных в записи.
Другая техника состоит в использовании пустых строк для разделения записей. По специальному соглашению пустая цепочка как значение RS может указывать, что записи разделяются одной или более пустыми строками. Если установить RS на пустую цепочку, запись всегда оканчивается на первой прочтенной пустой строке. И следующая запись не начинается, пока не появится первая непустая строка, следующая за любым количеством пустых строк, рассматриваемых как разделитель записей.
Того же самого эффекта, как от `RS = ""', можно достичь, присваивая RS цепочки ""n"n+". Это regexp соответствует newline в конце записи и одной или более пустых строк после записи. Кроме того, всякое регулярное выражение всегда соответствует наиболее длинной возможной последовательности, когда имеется возможность выбора (см. раздел 4.6 [Какая порция текста соответствует?], стр. 34). Так что следующая запись не начинается, пока не будет достигнута первая непустая строка, перед которой было сколько угодно пустых строк подряд, рассматриваемых как один разделитель записей.
Имеется важное различие между `RS = ""' и `RS = ""n"n+"'. В первом случае ведущие символы newline во входном файле данных игнорируются, и если файл оканчивается без дополнительных пустых строк после последней записи, конечная newline удаляется из записи. Во втором случае такая специальная обработка не производится (d.c.).
Теперь, когда ввод разделен на записи, следующий шаг состоит в разделении полей в записи. Один путь состоит в разделении каждой строки на поля обычным образом. Это происходит по умолчанию в результате следующей особенности: когда RS присвоена пустая цепочка string, символ newline всегда действует как разделитель полей. Это происходит дополнительно к всякому разделителю полей, проистекающему от FS. Исходным мотивом для этого специального исключения было, по-видимому, намерение добиться полезного поведения в случае действия по умолчанию (т.е. когда FS равно " "). Но это может привести к проблемам, если вы не хотите, чтобы символ newline разделял поля, поскольку нет способа предотвратить такое действие. Но можно обойти ситуацию, используя функцию split для расчленения записи вручную (см. раздел 12.3 [Встроенные функции для действий со строками], стр. 137).
Другой путь для отделения полей есть расположение полей на разных строках: чтобы сделать это, достаточно присвоить переменной FS цепочку ""n". (Это простое регулярное выражение соответствует одиночной newline.) Практическим примером файла данных, организованного таким образом, может быть список адресов, где члены списка разделены пустыми строками. Если список адресов находится в файле с именем `addresses', он выглядит примерно так:
Jane Doe 123 Main Street Anywhere, SE 12345-6789
John Smith 456 Tree-lined Avenue Smallville, MW 98765-4321
...
Простая программа обработки такого
файла будет подобна следующей:
# addrs.awk --- простая программа для список адресов
# Записи разделены пустыми строками.
# Каждая запись состоит из одного поля.
BEGIN - RS = "" ; FS = ""n" ""
-
print "Name is:", $1 print "Address is:",
$2 print "City and State are:",
$3 print "" ""
Исполнение программы породит следующий выход:
$ awk -f addrs.awk addresses
a Name is: Jane Doe
a Address is: 123 Main Street
a City and State are: Anywhere, SE 12345-6789
a
a Name is: John Smith
a Address is: 456 Tree-lined Avenue
a City and State are: Smallville, MW 98765-4321
a...
См. раздел 16.2.4 [Печать почтовых меток], стр. 233, где имеются более интересные программы с адресными списками. Следующая таблица содержит краткие сведения о разделении записей с помощью значения RS. (`==' означает "имеет значение")
RS == ""n" Записи разделены символами newline (`"n'). В действительности, каждая строка в файле данных есть отдельная запись, включающая пустые строки. Это --- действия по умолчанию.
RS == любой одиночный символ Записи разделяются вхождениями этого символа. Кратные последовательные вхождения ограничивают пустые записи.
RS == "" Записи разделяются группами пустых строк. Символ newline всегда означает разделитель полей, в дополнение к любому значению в FS. Ведущие и заключительные newline в файле игнорируются.
RS == regexp Записи разделяются вхождениями символов, соответствующих regexp. Ведущие и заключительные соответствия regexp ограничивают пустые записи.
Во всех случаях gawk присваивает RT входной текст, соответствующий значению, указанному в RS.
Назад | Вперед
Содержание (общее) | Содержание раздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|