【问题标题】:AWK set multiple delimiters for comma and quotes with commasAWK 为逗号和引号设置多个分隔符
【发布时间】:2015-09-14 01:02:48
【问题描述】:

我有一个 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'[,"]',但我得到的列比现有的多。

帮助表示赞赏。

【问题讨论】:

  • 尝试字段分隔符awk --field-separator="," "{ print NF }"
  • @authprivate 从不将 awk 脚本放在双引号中,--field-separator=","-F, 完全相同。要学习 awk,请阅读 Arnold Robbins 所著的《Effective Awk Programming, 4th Edition》一书。

标签: regex linux bash csv awk


【解决方案1】:

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

【讨论】:

  • 谢谢@John1024。如果在引号中还有其他引号来指定英寸,我们如何才能考虑到呢?请看我上面的例子。
  • @jxn 相应地更改FPATFPAT="([^,]+)|(\"([^\"]|\"\")+\")"
  • @lcd047 很好的建议。我将其添加到答案中。
  • 如果您在 FPAT 定义周围使用单引号而不是双引号,那么您不需要转义其中的所有双引号:-v FPAT='([^,]+)|("([^"]|"")+")'。此外,如果您想允许空字段(尝试abc,,def,"",ghi),您应该将+s 更改为*s:-v FPAT='([^,]*)|("([^"]|"")*")'
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多