filed1,filed2,field3,"field4,FOO,BAR",field5
我该如何在双引号内忽略逗号“,”,以便可以使用awk正确解析输出?我知道我们可以在Excel中做到这一点,但在awk中应该如何操作?
filed1,filed2,field3,"field4,FOO,BAR",field5
我该如何在双引号内忽略逗号“,”,以便可以使用awk正确解析输出?我知道我们可以在Excel中做到这一点,但在awk中应该如何操作?
zsh-4.3.12[t]% awk '{
for (i = 0; ++i <= NF;)
printf "field %d => %s\n", i, $i
}' FPAT='([^,]+)|("[^"]+")' infile
field 1 => filed1
field 2 => filed2
field 3 => field3
field 4 => "field4,FOO,BAR"
field 5 => field5
根据OP的要求添加一些注释。
FPAT的值应该是一个提供正则表达式的字符串。这个正则表达式描述了每个字段的内容。在上面提供的CSV数据的情况下,每个字段都是“不是逗号的任何东西”或“双引号,不是双引号的任何东西和一个结束双引号”。如果写成正则表达式常量,我们会有
/([^,]+)|("[^"]+")/
。将其写为字符串需要我们转义双引号,导致:
FPAT = "([^,]+)|(\"[^\"]+\")"
使用两次+
,这对于空字段不起作用,但也可以进行修复:
如所述,用于FPAT的正则表达式要求每个字段至少包含一个字符。简单的修改(将第一个“
+
”更改为“*
”)允许字段为空:
FPAT = "([^,]*)|(\"[^\"]+\")"
FS=","
似乎让 awk 完全忽略了 FPAT
,因为它没有转义带有嵌入逗号的引号字段。 - chrisbunneybrew install gawk
,并使用gawk
代替awk
πÇé - scottgwald当引号内有换行符和逗号时,FPAT 可以工作,但引号内有双引号时就无法工作,例如:
field1,"field,2","but this field has ""escaped"" quotes"
您可以使用我编写的一个简单的包装程序csvquote,使数据易于awk解释,然后恢复有问题的特殊字符,如下所示:
csvquote inputfile.csv | awk -F, '{print $4}' | csvquote -u
请查看 https://github.com/dbro/csvquote 以获取代码和文档。
BEGIN { FPAT = "(\"([^\"]|\"\")*\")|([^,\"]*)" }
- colemar完整的CSV解析器,如Perl的Text::CSV_XS
,专门用于处理这种奇怪的情况。
假设您只想打印第4个字段:
perl -MText::CSV_XS -lne 'BEGIN{$csv=Text::CSV_XS->new()} if($csv->parse($_)){ @f=$csv->fields(); print "\"$f[3]\"" }' file
输入行被拆分成数组@f
由于Perl从0开始索引,因此第4个字段是$f[3]
我在这里提供了有关Text::CSV_XS
的更多解释:使用gawk解析csv文件