如何在CSV中转义双引号?

时间:2018-12-05 08:20:01

标签: regex unix sed

我目前有几个csv文件,无法控制它们的创建方式。不用说...它们格式错误,不符合RFC 4180。

示例输入:gist

",0000000000000000";"0";"1115S021121-12-1/2"M"
",0000000000000000";"0";"1115S021122-12-1/2"M"
",0000000000000000";"0";"1115S021123-12-1/2"M"
",0000000000000000";"0";"1115S021124-12-1/2"M"
"1";"1";"EXAMPLE_RANDOM" .    STRING"
"2,0000000000000000";"2";"this;can"also happen"

所需:

",0000000000000000";"0";"1115S021121-12-1/2""M"

我一直试图通过使用正则表达式在其上运行sed来对其进行修复。但是我只具备正则表达式的基本知识,而sed不想与我的尝试打成一片。

有人可以帮助我在双引号内转义“”吗? 我知道这样的解决方案只有99%,我只能依靠以下事实。

  • 分隔符为;
  • 附件为“
  • ”可以在带引号的文本字段中多次出现。

这是一个;或“可能出现在引用的字段中。 有人可以帮助我将“替换为”吗?

我在正则表达式中尝试合并多个stackoverflow帖子。

 sed -E "s/[^\"](?<!;)\"(?!;|$)/\1"/g" $filename.test2   -> error
 sed "s/[^\"](?<!;)(\")(?!;|$)/\1/g" $filename.test2    -> error 
 ... about 10 more variations, some even without errors but no replaced strings.

如果有人有除正则表达式之外的其他解决方案,则非常感谢您的帮助!

编辑:感谢perch向导@choroba。以下内容可修复该文件。

 cat $filename.test | perl -pe 's/(?<=[^;])"(?=[^;])/""/g' >  $filename.test2

2 个答案:

答案 0 :(得分:4)

Perl对资源的环视断言!

perl -pe 's/(?<=[^;])"(?=[^;\n])/""/g' 

即如果存在"之前没有;且后面没有;的情况,则将其替换为""

答案 1 :(得分:2)

$ perl -MText::CSV_XS=csv -wE'csv(in=>csv(in=>"test.csv",sep=>";",allow_loose_quotes=>1,allow_loose_escapes=>1),always_quote=>1)'
",0000000000000000","0","1115S021121-12-1/2""M"
",0000000000000000","0","1115S021122-12-1/2""M"
",0000000000000000","0","1115S021123-12-1/2""M"
",0000000000000000","0","1115S021124-12-1/2""M"
"1","1","EXAMPLE_RANDOM"" .    STRING"
"2,0000000000000000","2","this;can""also happen"

正如choroba所说,用“;”作为输出sep:

$ perl -MText::CSV_XS=csv -wE'csv(in=>csv(in=>"test.csv",sep=>";",allow_loose_quotes=>1,allow_loose_escapes=>1),always_quote=>1,sep=>";")'
",0000000000000000";"0";"1115S021121-12-1/2""M"
",0000000000000000";"0";"1115S021122-12-1/2""M"
",0000000000000000";"0";"1115S021123-12-1/2""M"
",0000000000000000";"0";"1115S021124-12-1/2""M"
"1";"1";"EXAMPLE_RANDOM"" .    STRING"
"2,0000000000000000";"2";"this;can""also happen"

根据请求添加的说明:

Text :: CSV_XS是一个perl模块,可以以非常灵活的方式解析和生成CSV。使用选项/属性允许格式错误的CSV。

  1. csv(在=>“ file.csv”,...中)将文件读入内部结构

  2. sep =>“;”将分隔符设置为“;”而不是默认的“,”

  3. allow_loose_quotes => 1和allow_loose_escapes => 1使得可以读取错误的CSV并接受未转义的嵌套引号

  4. csv()返回对内部结构的引用,该内部结构对生成输出csv的外部csv调用有效(in => csv(in =>“ file.csv”)

    < / li>
  5. 最后两个参数将sep设置为“;”也需要输出,并导致所有字段都被引用,这是必需的OP

有关所有选项和示例,请参见https://metacpan.org/module/Text::CSV_XS

用脚本格式化,可能看起来像

use Text::CSV_XS qw( csv );

csv (                    # Outer function
    always_quote => 1,   # Quote all field
    sep          => ";", # Use ; instead of ,
    in           =>      # Input
        csv (            #   comes from inner function
            in                  => "test.csv", # a file
            sep                 => ";",        # ; instead of ,
            allow_loose_quotes  => 1,          # allow ,"foo"bar",
            allow_loose_escapes => 1,          # idem
            )
    );