【问题标题】:How do I replace double quotes within csv fields but not add a trailing double quote to each line?如何替换 csv 字段中的双引号,但不在每行添加尾随双引号?
【发布时间】:2013-01-23 16:01:31
【问题描述】:

我有一个名为 data_export_20130206-F.csv 的 csv 文件。它包含包含双引号 (") 的数据,这使得解析非常混乱。

文件看起来有点像这样(但有更多字段)

"stuff","zipcode"
"<?xml version="1.0" encoding="utf-8" ?>","90210"

我想“转义”字段中的引号,使其看起来像这样(注意:xml 中的引号已加倍):

"stuff","zipcode"
"<?xml version=""1.0"" encoding=""utf-8"" ?>","90210"

但是当我运行这个时:

cat data_export_20130206-F.csv| sed -E 's@([^,])(\")([^,])@\1""\3@g'

不幸的是,它在每行末尾添加了一个额外的双引号,使文档无效。

"stuff","zipcode""
"<?xml version=""1.0"" encoding=""utf-8"" ?>","90210""

如何替换 csv 字段中的双引号,但不在每行添加尾随双引号?

【问题讨论】:

  • 我认为这些行上可能有尾随空格。您应该首先摆脱它,然后您的 sed 应该可以工作

标签: regex csv sed


【解决方案1】:

确保在最后的 " 之前没有尾随空格,否则您的替换将匹配它。您也可以使用sed 来修剪尾随空格:

sed 's/\s\+$//' x.csv | sed -E 's@([^,])(\")([^,])@\1""\3@g'

【讨论】:

  • 另外,这会清除合并行的 $,我可以保留换行符吗?
【解决方案2】:

另一种方法是在第二遍中去掉多余的双引号:

sed -E 's@([^,])(\")([^,])@\1""\3@g' data_export_20130206-F.csv | sed 's,"\("$\),\1,'

或者干脆用tr 压缩所有重复的引号(但是如果任何字段以引号结尾,这会中断):

sed -E 's@([^,])(\")([^,])@\1""\3@g' data_export_20130206-F.csv | tr -s '"'

如果由于某种原因您仍会删除换行符,请在替换时读取它们:

sed -E 's@([^,])(\")([^,])@\1""\3@g' data_export_20130206-F.csv | sed 's,""$,"\n,'

【讨论】:

  • 这会清除合并行的 $,我可以保留换行符吗?
  • 真的吗?非常奇怪,你有什么样的 sed?我会用更安全的解决方案更新答案。
【解决方案3】:

这是一个脆弱的解决方案,但它适用于您提供的输入。

perl -pe 's/(?:^"|"(?=,)|"$|(?<=,)")//g;s/"/""/g;s/^/"/;s/$/"/;s/(?:(?=,)|(?<=,))/"/g' FILENAME

注意引号内的逗号会破坏这一点。 根据您的输入,生成了以下输出。

"stuff","zipcode"
"<?xml version=""1.0"" encoding=""utf-8"" ?>","90210"

【讨论】:

    猜你喜欢
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 2015-07-31
    • 2019-08-31
    相关资源
    最近更新 更多