如何将分隔符设置为 match() 函数中的参数?

How can i set the delimiter as an argument in the match() function?

awk '{while(match([=10=],/("[^"]+",|[^,]*,|([^,]+$))/,a)){
     [=10=]=substr([=10=],RSTART+RLENGTH);b[++x]=a[0]}
     print b[1] b[4];x=0}' file

我想了解 match 子句并想知道如何使其动态化以便它可以将分隔符作为参数而不是将其硬编码为逗号。

我试过了,但是没有用,因为我没有这个功能的背景。

awk -v dl '{while(match([=11=],/("[^"]+"dl|[^,]*dl|([^,]+$))/,a)){
     [=11=]=substr([=11=],RSTART+RLENGTH);b[++x]=a[0]}
     print b[1] b[4];x=0}' file

输入文件数据:

a,b,c,"d,e,f",  
"a,b",c,d,"e,f",  
p,q,r,"s,u",  

期望的输出(可能是第 4 个字段):

d,e,f  
e,f  
s,u  

期望的输出(可能是第 5 个字段,因此它应该生成具有空白值的 3 行):

在这里,分隔符可以是任何逗号、竖线和所需的字段号也是动态的。这就是为什么我想传递字段号和分隔符的参数。
字段编号参数工作正常但定界符参数不工作?

正如 Anubhava 所建议的那样,我使用了 fpat,它工作得很好,但是当从输入文件中获取第 5 列时它没有给出任何行?

那个正则表达式很奇怪,所以我会重写它。正则表达式:

/("[^"]+",|[^,]*,|([^,]+$))/

"[^"]+" 被解析为 - 第一个 " 和最后一个 " 是引号,[^"]+ 匹配除引号以外的所有内容。所以它是一样的:

"([^\"]+,|[^,]*,|([^,]+$))"

我猜您想匹配字段 [^,]+ 或带引号的字段 \"[^\"]+\" 后跟定界符或行尾 (,|$)。所以匹配。并且在匹配组匹配里面的字段,所以匹配\"([^\"]+)\"或者不带引号的字段([^,]+)然后使用那些匹配组

awk -v dl=, '{
    x = 0;
    while (match([=12=], "^(\"([^\"]+)\"|([^" dl "]+))(" dl "|$)", a)) {
        [=12=] = substr([=12=], RSTART + RLENGTH);
        b[++x] = a[2] a[3];   # funny, one of them will be empty
    }
    print b[4];
}' <<EOF
a,b,c,"d,e,f"
"a,b",c,d,"e,f"
p,q,r,"s,u"
EOF

d,e,f
e,f
s,u

使用gnu-awk,您可以定义一个FPAT变量,它是匹配字段的正则表达式。

awk -v FPAT='"[^"]*"|[^,]*' '{gsub(/"/, "", ); print }' file
d,e,f
e,f
s,u

运行 它来自 shell 以定界符作为参数的脚本:

dl="${1?}"
awk -v FPAT='"[^"]*"|[^'"$dl"']*' '{gsub(/"/, "", ); print }' "${2?}"

然后 运行 为:

bash p.sh ',' 'file'