Как использовать ^ # $ как разделитель записей в awk?

8

Как вы говорите awk использовать #символ в строке как разделитель записей? Проблема в том, что вы не можете сказать, RS="^#$"потому что ^соответствует началу файла, а не началу строки, и RS="#\n"не работает, потому что он соответствует #символам, которые не находятся в начале строки.

$ data='#
first record, first field
first record, second field
#
second record, first field#
second record, second field
'

Затем напечатайте первое поле каждой записи, используя RS="#\n":

$ printf "%s" "$data" | awk '
  BEGIN { RS="#\n"; FS="\n" }
  /./ {print $1}
  '
first record, first field
second record, first field
second record, second field

Последняя строка неверна, потому что это не первое поле, а второе. Предполагаемый результат был

first record, first field
second record, first field#
Эрнест А
источник
1
Не могли бы вы также привести пример
нужного
так ваши данные выглядят как line one#line two#line three?
Skaperen
а RS="#"чем занимается?
Skaperen
@Skaperen нет, данные выглядят так, #\nrecord one\n#\nrecord twoи каждая запись состоит из нескольких \nразделенных полей.
Эрнест А
RS='#\n'должен работать afaik - хотя он будет трактовать начальную #как завершение пустой записи (т.е. все NRзначения будут «выключены» на одну единицу)
steeldriver

Ответы:

6

Вот один из способов сделать это awk:

$ printf "%s\n" "$data" | 
    awk -F'\n' -v RS='(^|\n)#\n' '/./ {print $1}' 
first record, first field
second record, first field#

Хитрость заключается в том, чтобы установить в качестве разделителя записей либо начало файла ( ^), либо символ новой строки, за которым следует знак «a» #и другой символ новой строки \n.


Тердон
источник
1
Обратите внимание, что в этом случае NR будут одноразовыми (попробуйте заменить /./на NR==1). Я думаю, что самое простое решение было бы иметь конец файла / данных - вместо того, чтобы начинаться - с #в отдельной строке. затем\n#\n можно использовать как RS, и он будет работать правильно.
don_crissti
@don_crissti Я только что скопировал это из OP. Я предполагаю, что они используют его, чтобы избежать пустых строк, поэтому NR==1не будут работать, если есть еще пустые строки ниже.
Тердон