在shell脚本中按列拆分CSV,但不使用唯一分隔符

在shell脚本中按列拆分CSV,但不使用唯一分隔符,csv,awk,split,Csv,Awk,Split,我有一个包含多行的CSV,其中一些行如下所示 "ABC","Unfortunately, system has failed"," - Error in system" "DEF","Check the button labelled "WARNING"","Warning in system" "XYZ","Everythin

我有一个包含多行的CSV,其中一些行如下所示

"ABC","Unfortunately, system has failed"," - Error in system"
"DEF","Check the button labelled "WARNING"","Warning in system"
"XYZ","Everything is okay","No errors"
我需要拆分这些行并提取列,例如

我为每一行运行一个循环,并将第二列提取为

awk -F , '{print $2}' $line 
其中,
$line
表示每一行。然而,我最终得到了不正确的值。例如,当尝试获取第一行第二列时,使用上面的命令会给我
“不幸的是
而不是
“不幸的是,系统出现故障”


我知道我的字符串中同时包含逗号和引号,这使得基于分隔符进行拆分变得更加困难。还有什么我可以尝试的吗?

使用GNU awk和
FPAT

$ gawk '
BEGIN {
    FPAT="([^,]*)|(\"[^\"]+\")"
}
{
    print $2
}' file
输出:

"Unfortunately, system has failed"
"Check the button labelled "WARNING""
"Everything is okay"
它不是完整的CSV解析器,例如引号内的换行符未被处理,您需要自己处理它们(检查
NF
并合并记录)。有关
FPAT
的更多信息:

$ gawk '
BEGIN {
    FPAT="([^,]*)|(\"[^\"]+\")"
}
{
    print $2
}' file

如果要删除这些引用:

$ gawk '
BEGIN {
    FPAT="([^,]+)|(\"[^\"]+\")"
}
{
    for(i=1;i<=NF;i++)            # loop all fields
        gsub(/^"|"$/,"",$i)       # remove quotes surrounding fields
    print $2
}' file

如果要将输入数据放入3x3表格中 您可以使用
awk

awk -v FS=',[^ ]' -v OFS="|" '{print $1, $2, $3}' file
ABC"|Unfortunately, system has failed"| - Error in system"
"DEF"|Check the button labelled "WARNING""|Warning in system"
"XYZ"|Everything is okay"|No errors"
守则:

  • 为什么要设置
    FS=',[^]'
    ?系统中的逗号不是分隔符

我想知道,这在任何CSV方言中都是有效的吗?嵌入的双引号应该以某种方式转义。通常这是通过将它们加倍来完成的,比如
“检查标记为“WARNING”的按钮”
(是的,它很难看,但也很难看;它来自Microsoft。)在每一行上分别运行Awk效率低下,而且很难看。只需在整个文件上运行它;这就是它的构建目的(而shell在将输入拆分为行方面做得更糟)另外,@tripleee是的,我希望输入有转义双引号。不幸的是,输入是从不同的应用程序发送的,我们无法控制它们发送的格式。如果您没有GNU Awk,您可以使用
sed
来修饰每一行(即用其他分隔符替换
,“
)然后使用
awk
解析第二个字段,并用串联方式恢复包含的引号,例如
sed's/“,“/~/g'file.csv”| awk-F~'{print'\'$2'\'}'
——使用
'~'
作为修饰。通过替换整个模式
“\,”“
带有
”~'
——您知道要替换哪个
:)
您是如何获得此输出的?我尝试了您建议的同一个命令,得到的输出是
系统是
,那么您可能没有GNU Awk。@CluelessProgrammer您的
Awk--version
报告是什么?如果它没有报告GNU Awk——那么
FPAT
很可能不受支持。
Awk版本20070501
看起来您有一台Mac电脑,但没有安装GNU Awk。@JamesBrown-您的脚本现在可以完美地工作了。非常感谢你。必须阅读更多关于
FPAT
gawk
的内容。这些天我只使用了
awk
命令,但不是100%健壮,但我喜欢您选择的分隔符