AWK为逗号和逗号引号设置了多个分隔符

时间:2015-06-27 00:33:24

标签: regex linux bash csv awk

我有一个CSV文件,其中列以逗号分隔,并且引用带有逗号的文本数据的列。

有时,在引用文本中,也存在引号,表示像英寸这样的内容会产生更多引号。

没有嵌入逗号的文字数据没有引号。

例如:

A,B,C
1,"hello, how are you",hello
2,car,bike
3,13.3 inch tv,"tv 13.3"""

如何使用awk打印我应该获得的每一行的列数

3
3
3

我想过使用$awk -F'[,"]',但我的列数比现在多了。

帮助表示赞赏。

2 个答案:

答案 0 :(得分:9)

GNU awk有一个扩展来处理这些有问题的CSV文件。让我们首先考虑这一点,不要在引号中嵌入引号:

$ awk -v FPAT="([^,]+)|(\"[^\"]+\")" '{print NF}' file.csv
3
3
3

如何运作

FPAT不是通过分隔符定义字段,而是允许我们通过正则表达式定义字段。在这种情况下,我们将字段定义为没有逗号的内容,([^,]+),或者用双引号(\"[^\"]+\")包围的内容。

有关详细信息,请参阅the GNU manual

处理引号

中嵌入的引号

在问题的修订版中,我们有一行:

3,13.3 inch tv,"tv 13.3"""

在这种扩展的情况下,双引号可以包含在双引号字段中,如果它们本身加倍的话。为了实现这一目的,我们根据lcd047的建议扩展正则表达式,允许在字段中允许任意数量的这种双引号:

 awk -v FPAT="([^,]+)|(\"([^\"]|\"\")+\")"  '{print NF}' file.csv

答案 1 :(得分:3)

如果您关心字段内容,请使用@ John1024的解决方案,否则这就是您所需要的:

$ awk -F, '{gsub(/"[^"]+"/,""); print NF}' file
3
3
3