RS на языке awk
Я изучаю язык программирования awk, и я застрял здесь проблема.
У меня есть файл (awk.dat), имеющий следующее содержимое:
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci, euismod id nisi eget, interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis.
Я использую приведенную ниже команду:
awk 'BEGIN{RS="*, *";ORS="<<<---\n"} {print $0}' awk.dat
это возвращает мне ошибку:
awk: run time error: regular expression compile failed (missing operand)
*, *
FILENAME="" FNR=0 NR=0
Пока, если я использую команду: awk 'BEGIN{RS=" *, *";ORS="<<<---\n"} {print $0}' awk.dat
Дает требуемый результат.
Мне нужно понять эту часть: RS=" *, *"
, смысл пространства между двойными кавычками и *
до ,
, из-за чего выкидывает ошибку.
Ожидаемый результат:
Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci<<<---
euismod id nisi eget<<<---
interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat<<<---
et facilisis.
<<<---
Благодарю.
3 ответа
"[space1]*,[space2]*"
является регулярным выражением, оно соответствует строке с:
ноль или много пробелов (space1), за которыми следует запятая, затем следует ноль или много пробелов (space2)
Первый "*,[space]*"
был неправ, потому что *
имеет особое значение в регулярных выражениях. Это означает, что повторяющаяся совпадающая группа / символ ноль или много раз. Вы не можете поставить это в самом начале.
Имейте в виду, что, согласно POSIX, RS
определяется как один символ, а не как регулярное выражение.
Первый символ строкового значения
RS
должен быть разделителем входных записей;по умолчанию. Если RS
содержит более одного символа, результаты не указаны. ЕслиRS
равно нулю, то записи разделяются последовательностями, состоящими изплюс одна или несколько пустых строк, начальные или конечные пустые строки не должны приводить к пустым записям в начале или конце ввода, а всегда должен быть разделитель полей, независимо от значения FS
является.Источник: Awk Posix стандарт
Это подразумевает, что RS=" *, *"
приводит к неопределенному поведению.
Другие версии awk, которые реализуют расширения для POSIX, могут иметь другой подход к RS
обозначает. Примерами являются GNU awk и mawk. Оба реализуют RS
быть регулярным выражением, но обе реализации немного отличаются. Сводка по использованию <звездочки>:
| RS | awk (posix) | gawk | mawk |
|------+--------------+------------------+------------------|
| "*" | "<asterisk>" | "<asterisk>" | "<asterisk>" |
| "*c" | undefined | "<asterisk>c" | undefined |
| "c*" | undefined | "","c","ccc",... | "","c","ccc",... |
c is any character
Вышесказанное должно объяснить ошибку ОП как RS="*, *"
недопустимое регулярное выражение в соответствии с mawk.
$ echo "abc" | ./mawk '/*c/'
mawk: line 1: regular expression compile failed (missing operand)
GNU awk: Руководство по GNU awk гласит следующее:
Когда используешь
gawk
, стоимостьRS
не ограничивается односимвольной строкой. Это может быть любое регулярное выражение (см. Regexp). (ce) Как правило, каждая запись заканчивается следующей строкой, соответствующей регулярному выражению; следующая запись начинается в конце соответствующей строки.источник: руководство по GNU awk
Чтобы понять использование
<звездочка>
*
Этот символ означает, что предыдущее регулярное выражение должно повторяться столько раз, сколько необходимо, чтобы найти совпадение. Например,ph*
применяет*
символ предыдущегоh
и ищет совпадения одногоp
с последующим любым количествомh
s. Это также соответствует простоp
если нетh
с присутствуют.Есть два тонких момента, чтобы понять, как
*
работает. Во-первых,*
применяется только к одному предшествующему компоненту регулярного выражения (например, вph*
это относится только кh
). Вызывать*
чтобы применить к большему подвыражению, используйте круглые скобки:(ph)*
Матчиph
,phph
,phphph
, и так далее.Во-вторых,
*
находит как можно больше повторений. Если текст для сопоставленияphhhhhhhhhhhhhhooey
,ph*
соответствует всемh
s.источник: GNU Операторы регулярных выражений
Следует отметить, однако, что:
В
POSIX awkи gawk,*
,+
а также?
операторы отстаивают себя, когда в регулярном выражении нет ничего, что предшествует им. Например,/+/
соответствует буквальному плюсу. Однако многие другие версии awk рассматривают такое использование как синтаксическую ошибку.источник: GNU Операторы регулярных выражений
Таким образом, установка RS="*, *"
, подразумевает, что это будет соответствовать строкам "*,"
, "*, "
, "*, "
...
$ echo "a,b, c" | awk 'BEGIN{RS="*, *"}1'
a,b, c
$ echo "a*,b, c" | awk 'BEGIN{RS="*, *"}1'
a
b, c
mawk: Руководство по GNU awk гласит следующее:
12. Многострочные записи
посколькуmawk
толкуетRS
как регулярное выражение, многострочные записи просты.источник:
man mawk
но
11. Разделение строк, записей и файлов
Программы Awk используют один и тот же алгоритм для разбиения строк на массивы сsplit()
и записи в поля наFS
, mawk использует практически тот же алгоритм для разделения файлов на записиRS
,
Split(expr,A,sep)
работает следующим образом:
- <Вырезано>
- Если
sep = " "
(один пробел), затемобрезается спереди и сзади expr
, а такжеsep
становится <ПРОБЕЛ>. mawk определяеткак регулярное выражение /[ \t\n]+/
, Иначеsep
обрабатывается как регулярное выражение, за исключением того, что метасимволы игнорируются для строки длиной 1, например,split(x, A, "*")
а такжеsplit(x, A, /\*/)
подобные.- <Вырезано>
источник:
man mawk
В руководстве не упоминается, как следует интерпретировать регулярное выражение, начинающееся с метасимвола (например, "*c")
Примечание: в разделе GNU awk я описал POSIX awk, поскольку, согласно POSIX, регулярное выражение вида "*, "
приводит к неопределенному поведению. (Это не зависит от определения RS
как RS
в любом случае не ERE в POSIX awk)
Утилита awk должна использовать расширенную запись регулярного выражения (см. Расширенные регулярные выражения XBD)
Источник: Awk Posix стандарт
а также
*+?{
<Звездочка>, <знак плюс>, <знак вопроса> и <левая скобка> должны быть специальными, за исключением случаев, когда они используются в выражении в скобках (см. RE выражение в скобках). Любое из следующих применений приводит к неопределенным результатам:
- Если эти символы появляются первыми в ERE или сразу после неэкранированных <вертикальная линия>, <окружность>, <знак доллара> или <левая скобка>
- Если <левая скобка> не является частью правильного выражения интервала (см. ERE, соответствующие нескольким символам)
источник: расширенные регулярные выражения POSIX
Не могли бы вы попробовать следующий раз.
awk '{gsub(", ","<<<---" ORS)} 1;END{print "<<<---"}' Input_file