awk:为什么用空格定界,而不是FPAT正则表达式

时间:2018-11-13 07:17:40

标签: regex awk

我正在尝试拆分以','分隔的字符串,除非','位于括号中的子字符串中。在这里修改其他解决方案以及我尝试过此测试的文档中的示例:

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 :(得分:3)

使用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 explanation see this demo

答案 1 :(得分:2)

您的代码无效,因为,

  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