如何让awk忽略双引号内的字段分隔符?

Dee*_*K M 26 bash shell awk

我需要在逗号分隔值文件中删除2列.请考虑csv文件中的以下行:

"abc@xyz.com,www.example.com",field2,field3,field4
"def@xyz.com",field2,field3,field4
Run Code Online (Sandbox Code Playgroud)

现在,我想要的结果是:

"abc@xyz.com,www.example.com",field4
"def@xyz.com",field4
Run Code Online (Sandbox Code Playgroud)

我使用以下命令:

awk 'BEGIN{FS=OFS=","}{print $1,$4}'
Run Code Online (Sandbox Code Playgroud)

但是引号内的嵌入式逗号会产生问题,以下是我得到的结果:

"abc@xyz.com,field3
"def@xyz.com",field4
Run Code Online (Sandbox Code Playgroud)

现在我的问题是如何让awk忽略双引号内的","?

Ed *_*ton 38

从GNU awk手册(http://www.gnu.org/software/gawk/manual/gawk.html#Splitting-By-Content):

$ awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '{print $1,$4}' file
"abc@xyz.com,www.example.com",field4
"def@xyz.com",field4
Run Code Online (Sandbox Code Playgroud)

并看看使用awk有效解析CSV的最有效方法是什么?更常见地解析字段中包含换行符等的CSV.

  • @rubystallion您必须询问gawk开发人员内部发生了什么,但是正则表达式通常匹配最左最长的字符串,因此perl在`“ 1234 A Pretty Street`和`NE”`上以2 **个单独的字符串匹配**似乎是错误的,因为加上上面的awk和`grep -Eo'([^,] *)|(“ [^”] +“)'<<<'Robbins,Arnold,” 1234 A Pretty Street ,NE“,MyTown,MyState,12345-6789,USA'`将`” 1234 A Pretty Street,NE“`识别为单个字符串。当然,perl脚本可能包含一些神奇的咒语,表示“不匹配最左端的-最长”,idk,因为我没有获得perl语法。 (2认同)
  • @RalphCallaway 是的,FPAT 是一个 GNU awk 扩展。安装 gawk 或查看我的答案中的链接,了解适用于任何 awk 的解决方案。 (2认同)

4ae*_*1e1 10

这不是bash/awk解决方案,但我推荐CSVKit,可以安装pip install csvkit.它提供了一系列命令行工具,专门用于CSV,包括csvcut,它完全符合您的要求:

csvcut --columns=1,4 <<EOF
"abc@xyz.com,www.example.com",field2,field3,field4
"def@xyz.com",field2,field3,field4
EOF
Run Code Online (Sandbox Code Playgroud)

输出:

"abc@xyz.com,www.example.com",field4
def@xyz.com,field4
Run Code Online (Sandbox Code Playgroud)

它删除了不必要的引号,我认为这不应该是一个问题.

在RTD上阅读CSVKit的文档.ThoughtBot有一篇很好的小博客文章介绍了这个工具,这是我学习CSVKit的地方.

  • CSVKit太棒了!谢谢你介绍我:) (2认同)