В awk
скрипте я пытаюсь использовать ' (' в качестве разделителя полей. Однако, если я не экранирую скобки двойным обратным слешем, вот так:
BEGIN {FS=" \\("}
это не работает.
Если я использую, FS=" \("
я получаю
awk: prog:2: warning: escape sequence `\(' treated as plain `('
awk: prog:2: fatal: :, [., or [=: / (/
выводится, и если я вообще не выхожу за скобки, то получаю только
awk: prog:2: fatal: :, [., or [=: / (/
сообщение.
Можете ли вы объяснить такое поведение?
решение1
Чтобы использовать ␣(
(пробел+скобки) в качестве разделителя полей awk
, используйте "␣\\\("
:
$ echo "a (b (c" | awk -F " \\\(" '{ print $1; print $2; print $3 }'
a
b
c
В качестве альтернативы используйте одинарные кавычки и две обратные косые черты:
$ echo "a (b (c" | awk -F ' \\(' '{ print $1; print $2; print $3 }'
a
b
c
Причина этого в том, что ␣(
(одна скобкас(пробел) — неправильно сформированное регулярное выражение. Левая скобка открывает группировку, которая никогда не закрывается. Вот почему ее нужно экранировать.
Причина того, что (
(одна скобкабез(пробел в начале) работает так: когда FS
это один символ, он не рассматривается как регулярное выражение.
решение2
Я нашел эту ветку, когда искал решение похожей проблемы - использование ␣
OR (
в качестве разделителя полей для awk. Это не совсем ответ, но позвольте мне привести свое решение:
если вы хотите, чтобы комбинация ␣(
была единым целым для разделения файлов в awk, выполните awk -F '( \\()' ...
:
$ echo "This (maybe) is a test()" | awk -F '( \\()' '{print $1 "\n" $2 "\n" $3 "\n" $4 "\n" $5 "\n" $6 "\n" $7; print "Number of Fields: " NF}'
This
maybe) is a test()
Number of Fields: 2
Если вы ищете решение моей похожей проблемы - либо ␣
ИЛИ (
, сделайте awk -F '( |\\()' ...
:
$ echo "This (maybe) is a test()" | awk -F '( |\\()' '{print $1 "\n" $2 "\n" $3 "\n" $4 "\n" $5 "\n" $6 "\n" $7; print "Number of Fields: " NF}'
This
maybe)
is
a
test
)
Number of Fields: 7