处理 CSV 文件中字符串值中的逗号

pra*_*ker 4 awk text-processing csv

我有一个逗号分隔的文件,其中包含数字和字符串列。字符串列用引号引起来,引号之间可以有逗号。我如何识别列FS =","

样本记录

"prabhat,kumar",19,2000,"bangalore,India"
Run Code Online (Sandbox Code Playgroud)

AWK 中它应该是

$1 = "prabhat,kumar"
$2 = 19
$3 = "2000"
$4 = "bangalore,india"
Run Code Online (Sandbox Code Playgroud)

设置FS=","正在制造问题。

输入是:

"prabhat,kumar",19,2000,"bangalore,India","ABC,DEF","GHI",123,"KLM","NOP,QRS"
"prabhat,kumar",19,2000,"bangalore,India","ABC,DEF","GHI",123,"KLM","NOP,QRS"
Run Code Online (Sandbox Code Playgroud)

输出应该是:

"prabhat,kumar"|19|2000|"bangalore,India"|"ABC,DEF"|"GHI"|123|"KLM"|"NOP,QRS"
"prabhat,kumar"|19|2000|"bangalore,India"|"ABC,DEF"|"GHI"|123|"KLM"|"NOP,QRS"
Run Code Online (Sandbox Code Playgroud)

我正在尝试的代码:

awk -F"," '{for(i=1;i<=NF;i++){if(i%NF==0){ORS="\n"} {if($i ~ /^\"/ || $i ~ /\"$/) {a=a OFS $i;j++;{if(j%2==0){sub(/^\,/,X,a); print a;j=0;a=""}}} else {print $i}}} {ORS="|"}}' ORS="|" OFS=, p.txt
Run Code Online (Sandbox Code Playgroud)

ter*_*don 5

首先,您应该使用合适的 CSV 解析器。例如,在 Perl 中,您可以使用Text::CSV

  1. 安装cpanm(如果你使用 Perl,稍后你会感谢我)

    $ sudo apt-get install cpanminus
    
    Run Code Online (Sandbox Code Playgroud)

    如果您不是在基于 Debian 的系统上,您应该能够使用您的发行版的包管理器安装它。

  2. 安装Text::CSV模块

    $ sudo cpanm Text::CSV
    
    Run Code Online (Sandbox Code Playgroud)
  3. 解析你的文件

    $ perl -MText::CSV -le '
        $csv = Text::CSV->new({binary=>1}); 
        while ($row = $csv->getline(STDIN)){
        print "1:$row->[0], 2:$row->[1], 3:$row->[2], 4:$row->[3]"}' < file.csv 
    1:prabhat,kumar, 2:19, 3:2000, 4:bangalore,India
    
    Run Code Online (Sandbox Code Playgroud)

    正如你在上面看到的,第一个字段是$row->[0],第二个$row->[1]等等。


那是正确的方法。一个更简单但肮脏的黑客是用另一个字符替换任何带引号的逗号。然后,awk正常使用,最后,再次将它们切换回逗号。我在###这里使用,但你可以使用任何你确定永远不会出现在你的领域之一的东西。

$ sed -r 's/("[^",]+),([^",]+")/\1###\2/g' file.csv | 
    awk -F, '{print $1,$3}' | sed 's/###/,/g'
"prabhat,kumar" 2000
Run Code Online (Sandbox Code Playgroud)