删除回车符 (^M) 后的所有换行符并连接行

Ior*_*ppi 2 bash csv sed

编辑:既然我得到了答案,我标记了@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"
Run Code Online (Sandbox Code Playgroud)

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

"header_1", "header_2", "header_3"
"1-1", "1-2", "1-3"
"2-1", "2-2_a2-2_b2-2_c", "2-3"
Run Code Online (Sandbox Code Playgroud)

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

for file in *.csv; do
    sed -e "s/^M//" $file > sedded/$file;
done
Run Code Online (Sandbox Code Playgroud)

无论如何,我明白了:

"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"
Run Code Online (Sandbox Code Playgroud)

我尝试去做类似的事情"s/^M\n/",但它并没有像我怀疑的那样起作用。我应该使用完全不同的工具吗vim?只要它可以同时处理数千个文件(每个文件包含约 500 行,我并不关心处理所需的时间),我就可以接受任何类型的分辨率。只是认为sed是这样。(如果更简单或更直接的话,我可以使用 DOS 命令/powershell!)

Kam*_*ski 5

如果这些^M-s 确实是换行符,而不是字面脱字符号和字母 M 字符串,那么它们就是我们表示的\\rCR0x0d(比较我的这个答案,它的开头)。

\n\n

你的命令

\n\n
sed -e "s/^M//"\n
Run Code Online (Sandbox Code Playgroud)\n\n

不删除\\r; 它甚至不删除文字^M。该命令的意思是“取一行,搜索M该行最开头的一个字母(^参阅此),然后将其替换为空。

\n\n

注意sed了解\\r。仍然sed -e \'s/\\r//\'不完全是你所需要的。它会删除,但您还\\r需要删除以下内容。\\n你可能想尝试一下sed -e \'s/\\r\\n//\',这也会失败。问题是sed一个文本工具,它被视为\\n分隔符。摘录自info sed(强调我的):

\n\n
\n

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

\n
\n\n

这意味着通常\\n不属于使用s/\xe2\x80\xa6(或另一个sed命令)处理的任何字符串。因此,连接几行并不容易。还是可以做到的。这是您需要的命令:

\n\n
sed -e \': start; /\\r$/{ s/\\r$//; N; s/\\n// }; /\\r$/b start\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

解释:

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