awk: Почему разделители пробелов вместо регулярных выражений FPAT - PullRequest
0 голосов
/ 13 ноября 2018

Я пытаюсь разбить строки, разделенные ',', за исключением случаев, когда ',' находится в подстроке, заключенной в скобки. Модифицируя другие решения здесь и примеры в документах, я попробовал этот тест:

awk -v FPAT='([^,]+)|(\([^\))+\))' '{
    for (i=1; i<=NF; i++) {
        printf("%s\n", $i)
    }                     
}' <<< 'one two (1one), three four (3three, 4four), five six, seven eight, nine ten eleven (8ten)'
one
two
(1one),
three
four
(3three,
4four),
five
six,
seven
eight,
nine
ten
eleven
(8ten)

FPAT не переопределяет разделитель по умолчанию, как я ожидал. так ясно, что я что-то упускаю.

Вывод, который я хочу получить:

one two (1one),
three four (3three, 4four),
five six,
seven eight, 
nine ten eleven (8ten)

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

Использование gnu grep:

s='one two (1one), three four (3three, 4four), five six, seven eight, nine ten eleven (8ten)'
grep -oP '\s*\K([^,(]*\([^)]*\))*[^,]*(,|$)' <<< "$s"

one two (1one),
three four (3three, 4four),
five six,
seven eight,
nine ten eleven (8ten)

Если у вас нет gnu grep, тогда вы можете использовать

grep -oE '([^,(]*\([^)]*\))*[^,]*(,\s*|$)' <<< "$s"

, который будетоставьте завершающие пробелы после запятой.

Для объяснения regex см. это демо .

0 голосов
/ 13 ноября 2018

Ваш код не работает, потому что

  1. ([^,]+)|(\([^\))+\)) является недопустимым регулярным выражением, в нем есть непревзойденный [,
  2. Вы говорите, что используете mawk, но он не поддерживает FPAT.

Вот решение FPAT, с которым я столкнулся

$ cat file
one two (1one), three four (3three, 4four), five six, seven eight, nine ten eleven (8ten)
$
$ awk -v FPAT='[^,(]*(\\([^)]*\\))?(, |$)' '{ for (i=1; i<=NF; ++i) print $i }' file
one two (1one),
three four (3three, 4four),
five six,
seven eight,
nine ten eleven (8ten)

Объяснение FPAT переменной:

  • [^,(]* соответствует любому количеству символов без запятых, без скобок,
  • \\([^)]*\\) соответствует любому числу символов без скобок, заключенных в скобки,
    • Если ввести это значение в (...)?, это совпадение будет необязательным.
  • (, |$) означает, что сопоставляемое поле должно заканчиваться запятой, за которой следует пробел, или оно должно быть последним полем в строке.

А вот как это сделать в mawk

mawk '{ gsub(/[^,(]*(\([^)]*\))?, /, "&\n") }1'  file

sed можно использовать и для этого конкретного случая

sed 's/[^,(]*\(([^)]*)\)\?, /&\n/g'  file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...