【问题标题】:Add double quotes around all the fields in CSV file [duplicate]在 CSV 文件中的所有字段周围添加双引号 [重复]
【发布时间】:2019-04-03 10:40:11
【问题描述】:

我想在 CSV 文件的所有字段中添加引号。

我的 CSV 文件

$ cat file.csv
1,563,45645,example-text,/example/path,FILE,ftp://,11 

预期输出

$ cat file.csv
"1","563","45645","example-text","/example/path","FILE","ftp://","11"

【问题讨论】:

  • 请在未来也加入你自己的努力......最简单的是sed 's/[^,]*/"&"/g'
  • 这些答案都不是特别健壮的,因为如果在某些字段已经被引用的地方给出输入,它们会中断,所以这里是使用 Text::CSV_XS 模块的 perl 单行:perl -MText::CSV_XS -e 'my $csv = Text::CSV_XS->new({always_quote=>1});while (my $r = $csv->getline(\*STDIN)) { $csv->say(\*STDOUT, $r) }' < file.csv in有可能的情况
  • @Shawn 您的陈述不正确。我的回答确实解决了这个问题。 Perl 很好!
  • @kvantour 您的 awk 不处理带逗号的引用字段。除非您知道您的输入没有这样的内容(OP 的数据很可能就是这种情况),否则用逗号进行天真的拆分不是处理 CSV 数据的方法。
  • @Shawn 有效点!

标签: csv awk sed text-manipulation


【解决方案1】:

试试 Perl

$ cat smc.txt
1,563,45645,example-text,/example/path,FILE,ftp://,11
$ perl -lpe ' s/([^,]+)/"$1"/g ' smc.txt
"1","563","45645","example-text","/example/path","FILE","ftp://","11"
$

或使用环视法

$ perl -lne  ' s/^|(?<=,)|(?=,)|$/"/g  ; print ' smc.txt
"1","563","45645","example-text","/example/path","FILE","ftp://","11"
$

【讨论】:

    【解决方案2】:

    有许多简单直接的方法可以按照您想要的方式格式化您的 CSV 文件。但是,如果您希望 CSV 文件符合 RFC 1410 标准,则必须更加小心。尤其是规则 7:

    1. 如果使用双引号将字段括起来,则使用双引号 出现在字段中必须通过在其前面加上另一个双引号来进行转义。例如:
        "aaa","b""bb","ccc"
    

    来源:RFC 1410: Common Format and MIME Type for CSV Files

    这给出了以下 awk 解决方案:

    awk 'BEGIN{FS=OFS=","}
         { 
           for(i=1;i<=NF;++i) { 
             gsub("\042","\042\042",$i)
             sub("^\042\042","",$i)
             sub("\042\042$","",$i)
             $i="\042" $i "\042"
           }
         }1' file.csv
    

    此外,如果您希望遵守规则 1:

    1. 每条记录位于单独的行上,由一行分隔 休息(CRLF)。例如:
        aaa,bbb,ccc CRLF
    
        zzz,yyy,xxx CRLF
    

    来源:RFC 1410: Common Format and MIME Type for CSV Files

    awk 'BEGIN{FS=OFS=","; ORS="\r\n"}
         { 
           sub("\r$","")
           for(i=1;i<=NF;++i) { 
             gsub("\042","\042\042",$i)
             sub("^\042\042","",$i)
             sub("\042\042$","",$i)
             $i="\042" $i "\042"
           }
         }1' file.csv
    

    【讨论】:

      【解决方案3】:

      试试这个:

      sed "s/,/\",\"/g;s/\(.*\)/\"\1\"/" file.csv
      

      解释:

      s/           # substitute
      ,/           # all ,
      \",\"        # with ","
      /g           # global on whole line
      ;            # next expression
      s/           # substitute
      \(.*\)/      # save all into arg1 (\1)
      \"\1\"/      # change to "\1"
      

      【讨论】:

      • 最后一部分可以简化为s/^\|$/"/g,如果你使用单引号,你可以去掉所有的反斜杠:'s/,/","/g;s/^\|$/"/g'
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-07
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 1970-01-01
      相关资源
      最近更新 更多