在awk中用双引号转义分隔符

时间:2011-10-18 08:52:28

标签: awk delimiter double-quotes separator

我使用awk用“,”解析我的数据作为分隔符,因为输入是一个csv文件。但是,数据中有“,”用双引号(“...”)转义。

实施例

filed1,filed2,field3,"field4,FOO,BAR",field5

如何在双引号中忽略逗号“,”以便我可以使用awk正确解析输出?我知道我们可以在excel中做到这一点,但我们如何在awk中做到这一点?

3 个答案:

答案 0 :(得分:22)

使用 GNU awk 4

很容易
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要求添加一些注释。

来自GNU awk manual on "Defining fields by content

  

FPAT的值应该是一个提供常规字符串的字符串   表达。这个正则表达式描述了每个的内容   领域。在如上所述的CSV数据的情况下,每个字段是   “任何不是逗号的东西”,或“双引号,任何东西   这不是一个双引号,而是一个收尾双引号。“如果写成   正则表达式常量,我们将/([^,]+)|("[^"]+")/。把它写成一个字符串   要求我们逃避双引号,导致:

     

FPAT = "([^,]+)|(\"[^\"]+\")"

使用+两次,这对空字段无效,但也可以修复:

  

如上所述,用于FPAT的正则表达式要求每个字段至少包含一个字符。直接修改(将第一个“+”更改为“*”)允许字段为空:

     

FPAT = "([^,]*)|(\"[^\"]+\")"

答案 1 :(得分:11)

当引号字段中有换行符和逗号时,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了解代码和文档

答案 2 :(得分:1)

完全成熟的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
字段4是$f[3],因为Perl开始索引为0

我在答案中提供了Text::CSV_XS的更多解释:parse csv file using gawk