需要一种方法从记录中间剥离额外的 CRLF

Need a way to strip extra CRLFs from the middle of records

我们有一个数据源,它向我们发送我们需要自动导入系统的文件,但在某些记录的一两个字段中,它们经常以额外的 CRLF 形式存在错误数据。该文件是一个 CSV 格式文件,最初我以为我已经解决了这个问题:

awk 'NR%2-1{gsub(/\r?\n/, FS)} NR>1{printf RS}1' RS=\" ORS= input.csv > output.csv

这对于在引号内有额外 CRLF 的记录非常有用,但事实证明我们也得到了一些没有引号的记录,这会导致 awk 命令关闭。

每条记录的最后一个字段是一个由 4-7 位数字组成的数字字段,有什么方法可以将其用作参考来保留该字段后面的 CRLF 并删除其余部分?

或者,是否有一些方法可以通过计算字段数并删除记录中最后一个字段之前的字段来去除 CRLF?

输入如下所示:

SMITH,John,,,,,,05/10/1966,,USA,USA,A 5551212,"Resides in California, USA",,,,Mill Valley,,,,,USA,"Northern District of California, USA",Individual,,,12/09/2003,18/08/2015,78452
SMITH,Patty,,,,,,05/10/1974,,USA,USA,A 5551212,"Resides in Oregon, USA",,,,Portland,,,,,USA,"District of Oregon, USA",Individual,,,15/09/2002,02/02/2015,121567

问题记录如下所示 - 注意回车 return 和遗漏的引号:

SMITH,Bill,,,,,,05/10/1966,,USA,USA,A 5551212,"Resides in California, USA",,,,Mill Valley,,,,,USA,Northern District of
California, USA,Individual,,,12/09/2003,18/08/2015,78452

对于输出,我们需要记录与其他两个相同 - 都在一行上:

SMITH,Bill,,,,,,05/10/1966,,USA,USA,A 5551212,"Resides in California, USA",,,,Mill Valley,,,,,USA,Northern District of California, USA,Individual,,,12/09/2003,18/08/2015,78452

如果您只需要删除字段内部 CRLF,请尝试以下操作(假设 GNU awk,但它可以与 BSD 一起使用awk 还有):

awk -v RS='\r?\n' '/,[[:digit:]]{4,7}$/ { print; next } { printf("%s ", [=10=]) }' input.csv > output.csv
  • /,[[:digit:]]{4,7}$/ 仅匹配以 4-7 位数字结尾的行,这意味着手头的行是完整记录或者是多行记录的 last线。
    • { print; next } 只是打印带有终止符 \n 的行(如果您也想在输出中使用 \r\n,则必须改用 printf("%s\r\n", [=17=]))。
  • { printf("%s ", [=18=]) } 然后只打印记录 片段 ,即具有字段内部 CRLF 的记录,因此在下一行继续;通过使用 printf 和尾随的 space 打印它,最终效果是包含单个记录的多行有效地与 space 连接每个都输出。