使用逗号分隔的csv文件解析问题

时间:2010-03-18 12:56:19

标签: parsing awk

我正在尝试使用此命令从csv文件中提取第4列(以逗号分隔,并跳过前2个标题行),

 awk 'NR <2 {next}{FS =","}{print $4}' filename.csv | more

但是,它不起作用,因为第一列可以逗号,因此第4列不是第4列。以下是一行示例:

“sdfsdfsd,sfsdf”,454,fgdfg,I_want_this_column,sdfgdg,34546,456465等

5 个答案:

答案 0 :(得分:3)

除非您有使用awk的具体原因,否则我建议您使用CSV解析库。许多脚本语言都有一个内置(或至少可用),它们可以帮助您避免这些麻烦。

答案 1 :(得分:1)

如果您的第一列始终有引号,

 $ awk 'BEGIN{ FS="\042[ ]*," } { m=split($2,a,","); print a[3] } ' file
 I_want_this_column

如果您想要的列始终是最后一个,

$ awk -F"," '{print $(NF-1)}' file
 I_want_this_column

您可以尝试使用此演示脚本来细分列

awk 'BEGIN{ FS="," }
{
   for(i=1;i<=NF;i++){
      # save normal
      if($i !~ /^[ ]*\042|[ ]*\042[ ]*$/){
        a[++j]=$i
      }
      # if quotes at the end
      if(f==1 && $i ~ /[ ]*\042[ ]*$/){
        s=s","$i
        a[++j]=s
        #reset
        s="";f=0
      }
      # if quotes in front
      if($i ~ /^[ ]*\042/){
        s=s $i
        f=1
      }
      if(f==1 && ( $i !~/\042/ ) ){
         s=s","$i
      }
   }
}
END{
  # print columns
  for(p=1;p<=j;p++){
     print "Field "p,": "a[p]
  }
} ' file

输出

$ cat file
"sdfsdfsd, sfsdf", "454,fgdfg blah , words ", I_want_this_column,sdfgdg

$ ./shell.sh
Field 1 : "sdfsdfsd, sfsdf"
Field 2 : fgdfg blah
Field 3 :  "454,fgdfg blah , words "
Field 4 :  I_want_this_column
Field 5 : sdfgdg

答案 2 :(得分:0)

你不应该在这里使用awk。使用Python csv模块或Perl Text :: CSV或Text :: CSV_XS模块或其他真正的csv解析器。

相关问题 - parse csv file using gawk

答案 3 :(得分:0)

如果你无法避免awk,这段代码可以完成你需要的工作:

BEGIN {FS=",";}

{
        f=0;
        j=0;
        for (i = 1; i <=NF ; ++i) {
                if (f) {
                        a[j] = a[j] "," $(i);
                        if ($(i) ~ "\"$") {
                                f = 0;
                        }
                }
                else {
                        ++j;
                        a[j] = $(i);
                        if ((a[j] ~ "^\"[^\"]*$")) {
                                f = 1;
                        }
                }
        }
        for (i = 1; i <= j; ++i) {
                gsub("^\"","",a[i]);
                gsub("\"$","",a[i]);
                gsub("\"\"","\"",a[i]);
print "i = \"" a[i] "\"";
        }
}

答案 4 :(得分:0)

使用标准的UNIX文本工具,使用带有逗号的引用字段的CSV文件很困难。

我编写了一个名为csvquote的程序,使数据易于处理。在您的情况下,您可以像这样使用它:

csvquote filename.csv | awk 'NR <2 {next}{FS =","}{print $4}' | csvquote -u | more

或者你可以像这样使用剪切和尾巴:

csvquote filename.csv | tail -n +3 | cut -d, -f4 | csvquote -u | more

代码和文档位于:https://github.com/dbro/csvquote