Unix 文件在引号内包含换行符

Kum*_*mar 3 bash text-processing csv

我有一个 CSV 奇怪的文件,其中引号内有引号,换行符以及一列中没有的内容。现在我需要将该列标识为“换行符”作为一列,并用一些分隔符替换换行符。

我有 3 列,第三列将包含一些带有双引号和每个特殊字符的 HTML 文本。但双引号是用双引号转义的,比如"<This ""is"" string>".

输入:

ID、姓名、文字

"1","abc","Line 1"
"2","def","Line2
""line2"",line2"
"3","ghi","line3"
Run Code Online (Sandbox Code Playgroud)

输出:

ID, Name, text
"1","abc","Line 1"
"2","def","Line2 ""line2"",line2"
"3","ghi","line3"
Run Code Online (Sandbox Code Playgroud)

Kus*_*nda 6

您的文件没有真正的问题。它嵌入了换行符和双引号。CSV 解析器能够正确处理它。使用转义双引号"(同时双引号字段)是转义 CSV 文件中嵌入双引号的正确方法。

要将CSV 文件中嵌入的@换行符替换为字符,您可以执行以下操作:

$ csvformat -M '@' file.csv | tr '\n@' '@\n'
1,abc,Line 1
2,def,"Line2@""line2"",line2"
3,ghi,line3
Run Code Online (Sandbox Code Playgroud)

这使用csvformatcsvkit工具箱。它是一个合适的 CSV 解析器,能够重新格式化 CSV 文件。

上面的命令管道首先替换所有未嵌入该@字符的换行符。然后我用来tr交换剩余的换行符和@字符,最终得到一个嵌入换行符为 的 CSV 文件@。

这依赖于文件中的原始数据不包含@字符的事实。

如果您想要使用空格而不是换行符最初所在位置的标记,请使用而tr '\n@' ' \n'不是tr上面显示的:

$ csvformat -M '@' file.csv | tr '\n@' ' \n'
1,abc,Line 1
2,def,"Line2 ""line2"",line2"
3,ghi,line3
Run Code Online (Sandbox Code Playgroud)

请注意,如果数据中存在其他空格(如第一行的第三个字段中那样),这将使重新插入原始换行变得极其困难。

您是否希望csvformat不删除所有不必要的双引号,然后将其与以下命令一起使用-U 1:

$ csvformat -U 1 -M '@' file.csv | tr '\n@' ' \n'
"1","abc","Line 1"
"2","def","Line2 ""line2"",line2"
"3","ghi","line3"
Run Code Online (Sandbox Code Playgroud)

使用 Miller 得到更简单的答案(2022 年 10 月):

$ csvformat -M '@' file.csv | tr '\n@' '@\n'
1,abc,Line 1
2,def,"Line2@""line2"",line2"
3,ghi,line3
Run Code Online (Sandbox Code Playgroud)
$ csvformat -M '@' file.csv | tr '\n@' ' \n'
1,abc,Line 1
2,def,"Line2 ""line2"",line2"
3,ghi,line3
Run Code Online (Sandbox Code Playgroud)

这会读取 CSV 文件(假设有正常的标头)并用空格gsub()替换字段中的任何换行符。text