删除回车符 (^M) 后的每个换行符并连接各行

删除回车符 (^M) 后的每个换行符并连接各行

编辑:现在我得到了答案,我标记了一个由@KamilMaciorowski 提供的更适合标题的答案,但是@oliv 的回答实际上更适合我的主要目的。(在 awk 上一致地处理带有中断的 csv 文件。)

因此,如果您在类似情况下寻找 awking,我建议您先检查一下!


请帮我准备几千个 csv 文件以供awk处理!有些字段内部有换行符,这导致将awk它们作为多条记录处理。但是那些有问题的换行符只发生在插入 ^M 的地方,所以我只是需要从所有文本中删除 ^M 和换行符。

*这些^Ms 确实是换行符,而不是文字插入符号和字母 M 字符串。此文件是为 .net 解析和处理而生成的,但我没有在文件生成/读取端开发应用程序,所以我真的不知道它是如何成功解析的。它专门用于具有多行字符串(注释)的某些列中的字段。

那么你如何制作这个(带有 1 个标题和 2 个记录的 csv。某些字段中有以 ^M 开头的换行符):

"header_1", "header_2", "header_3"
"1-1", "1-2", "1-3"
"2-1", "2-2_a^M
2-2_b^M
2-2_c", "2-3"

像这样吗?(csv 有 1 个标题和 2 个记录,每个记录内没有换行符。):

"header_1", "header_2", "header_3"
"1-1", "1-2", "1-3"
"2-1", "2-2_a2-2_b2-2_c", "2-3"

我尝试用它们移除,sed但听说没有办法处理,而且我也不太明白原因。

for file in *.csv; do
    sed -e "s/^M//" $file > sedded/$file;
done

无论如何,我明白了:

"header_1", "header_2", "header_3"
"1-1", "1-2", "1-3"
"2-1", "2-2_a
2-2_b
2-2_c", "2-3"

我尝试过类似的东西"s/^M\n/",但它并没有像我怀疑的那样起作用。我应该使用完全不同的工具吗vim?只要它能同时处理数千个文件(每个文件包含约 500 行,我并不关心处理所需的时间),我对任何解决方案都满意。只是觉得sed这样就行了。(如果更简单或更直接,我可以使用 DOS 命令/powershell!)

答案1

如果这些^M-s 确实是换行符,而不是文字插入符号和字母 M 字符串,那么它们就是我们所说的\rCR或者0x0d(比较这是我的答案,它的开始)。

您的命令

sed -e "s/^M//"

不会删除\r;它甚至不会删除文字^M。该命令的意思是“取一行,搜索M行首的字母(^看到这个),将其替换为无。

注意sed理解\r。仍然sed -e 's/\r//'不是您真正需要的。它会删除,但您还\r需要删除以下内容。您可能想尝试,这也会失败。问题是是一个文本工具,它将其视为分隔符。摘录自(重点是我的):\nsed -e 's/\r\n//'sed\ninfo sed

sed通过对输入的每一行执行以下循环来操作:首先,sed从输入流中读取一行,删除任何尾随的换行符,并将其放置在模式空间中。然后执行命令;[…]。

这意味着通常\n不属于任何处理的字符串s/…(或其他sed命令)。因此,连接几行并不容易。仍然可以办到。这是您需要的命令:

sed -e ': start; /\r$/{ s/\r$//; N; s/\n// }; /\r$/b start'

解释:

  • : start是一个标签。
  • 如果该行最后包含\r(即^M字符)( ),则执行以下块: 0x0d${}
    • \r在最后用空替换,
    • 从输入中附加一行(N),
    • 替换\n将附加行与先前的数据分开。
  • 如果结果\r在最后包含(意味着额外的行带来了它,所以我们需要添加另一行),则跳转到start

答案2

假设每行有 3 个字段,并且任何值内都没有双引号,则可以使用此 GNU awk 脚本:

awk -v FPAT='"[^"]*"' '{while(NF!=3){p=$0;getline;gsub("^",p)}; p=""}1' file

FPAT定义字段的外观,即用双引号括起来的任何内容。

awk 语句通过从文件中获取行来构建记录,直到有 3 个字段。

相关内容