【问题标题】:Remove field-internal newlines in CSV file删除 CSV 文件中的字段内部换行符
【发布时间】:2022-01-27 20:24:21
【问题描述】:

我尝试了不同的 awk 方法来实现这一点,但由于我不太了解 awk 的工作原理,所以我没有成功。

所以,我有一个 - 大 - csv 文件,其中包含多行条目,例如:

"99999";"xyz";"text

that has

multiple newlines";"fdx";"xyz"

我需要去掉引号之间的那些多余的换行符。

由于每一行都以双引号结尾,后跟换行符,我想我可以创建一个替换所有换行符的命令,除了前面有双引号的换行符。

我该怎么做?

【问题讨论】:

  • 您搜索了什么,找到了什么?你尝试了什么,它是如何失败的?使用具有强大且经过良好测试的 CSV 解析器的工具(例如 Python)可能会更容易,而不是自己从第一原则重新构建。
  • 但本质上,如果你有不成对的报价,收集更多的行直到你再次有报价,然后对你收集的数据进行后处理。
  • 试试这个sed 命令:sed '/^$/D' infile | sed -e :a -e '$!N;s/[^"]\n"/"/;ta' -e 'P;D' ``
  • 谢谢大家 - 我找到了实现我想要的所需的正则表达式:(?<!")\n 但遗憾的是 awk 不支持前瞻/前瞻。

标签: awk


【解决方案1】:

您需要的就是这个,使用 GNU awk 进行多字符 RS:

awk -v RS='\r\n' '{gsub(/\n/," ")}1' file

因为您的输入可能是从 Excel 等 Windows 工具导出的 CSV,因此有 \r\n“行”结尾,但字段中的换行符有单独的 \ns。

或者,再次将 GNU awk 用于多字符 RS 和 RT:

$ awk -v RS='"[^"]+"' -v ORS= '{gsub(/\n/," ",RT); print $0 RT}' file
"99999";"xyz";"text  that has  multiple newlines";"fdx";"xyz"

或者,如果您希望将所有换行链压缩为单个空格:

$ awk -v RS='"[^"]+"' -v ORS= '{gsub(/\n+/," ",RT); print $0 RT}' file
"99999";"xyz";"text that has multiple newlines";"fdx";"xyz"

如果您需要其他任何东西,包括能够识别和使用每个输入“行”上的各个字段,请参阅What's the most robust way to efficiently parse CSV using awk?

【讨论】:

  • 已经试过了。但不幸的是,它不是 Excel 导出,而是来自我无法控制的 CRM。
  • 好的,那么这是我链接的现有问题的副本,即使字段包含转义的引号或分隔符(在您的情况下为;s),您也必须假设可能会发生这种文件。因为您无法控制输入。
  • OMG - 看起来非常复杂。不过,我会试一试。谢谢!
  • 是的,对于一般情况,要稳健有效地解决这是一个复杂的问题。或者,您可以使用专门支持解析 CSV 的工具。不客气。
  • 如果 awk 支持前瞻,那将是一件轻而易举的事,因为 awk -v RS='(?<!")\n' -v ORS= '{gsub(/\n/, " ", RT); print $0 RT}' file 会这样做...... :) 但不支持前瞻,所以这会产生错误
猜你喜欢
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 2015-08-18
  • 1970-01-01
相关资源
最近更新 更多