使用 sed 将 \s+ 分隔文件转换为 csv

Posted

技术标签:

【中文标题】使用 sed 将 \\s+ 分隔文件转换为 csv【英文标题】:converting \s+ delimited file to csv using sed使用 sed 将 \s+ 分隔文件转换为 csv 【发布时间】:2021-10-13 10:53:59 【问题描述】:

我正在尝试转换每列有两个或多个空格分隔的文件。

YP_010083342.1       -            258 VOG00003             -            582   8.6e-22   80.7   0.2   1   1   5.3e-25     1e-21   80.4   0.2   193   363     5   185     1   251 0.60 anti-repressor protein [Staphylococcus phage LH1]

我想使用 sed 将其转换为 csv。以下 sed 命令对文件没有明显的更改。

sed -i 's/\s+/,/g' file.ouput
sed -i 's/$\s+/,/g' file.ouput
sed -i 's/\t+/,/g' file.ouput
sed -i 's/$\t+/,/g' file.ouput

但以下命令会导致以下结果

sed -i 's/\s\s/,/g' file.ouput

YP_010083342.1,,, -,,,,,,258 VOG00003,,,,,, -,,,,,,582, 8.6e-22, 80.7, 0.2, 1, 1, 5.3e-25,, 1e-21, 80.4, 0.2, 193, 363,, 5, 185,, 1, 251 0.60 anti-repressor protein [Staphylococcus phage LH1]

有谁能解释为什么会发生这种情况以及如何正确解决这个问题?

【问题讨论】:

也许尝试使用\h 而不是\s...? 为什么“使用 sed”是问题的一部分?您真的不会接受使用 awk 或在没有外部工具的纯原生 bash 中实现的答案吗? 我很乐意在 awk 或其他工具中得到答案,但我特别想加深对这个 sed 命令如何工作的理解。 在这种情况下,最好的位置可能是从relevant POSIX standard 开始。请注意,POSIX 标准化的sed 不支持\s,因此最好避免这种情况。当您想匹配不同类型的空格时,请改用[[:space:]] 以获得更好的兼容性。 (在上述规范中,您可以找到一个到BRE regex syntax 的链接,它指定了所有符合标准的sed 版本都需要支持的正则表达式格式;有些超出了该标准,但是当您编写该标准时,您知道您的代码将在任何地方运行)。 【参考方案1】:

你可以使用这个sed

sed -E 's/ 2,/,/g' file

YP_010083342.1,-,258 VOG00003,-,582,8.6e-22,80.7,0.2,1,1,5.3e-25,1e-21,80.4,0.2,193,363,5,185,1,251 0.60 anti-repressor protein [Staphylococcus phage LH1]

或者这个awk

awk -F ' 2,' -v OFS=, '$1=$1 1' ff

【讨论】:

【参考方案2】:

问题在于+ 是扩展正则表达式的一部分,必须使用sed -r(或-E)启用。一些 sed,如 GNU sed 也支持它作为基本正则表达式的扩展,但它必须被转义:\+。顺便说一句,\s 也是一个扩展。

假设 GNU sed,这些都可以工作:

sed -i 's/\s\s\+/,/g' file.output
sed -E -i 's/\s\s+/,/g' file.output
sed -E -i 's/\s2,/,/g' file.output

更便携,可使用任何 sed(将输出重定向到另一个文件,然后重命名):

sed 's/[[:blank:]]\2,\/,/g' file.output

【讨论】:

谢谢,这有助于理解,但不幸的是,这些行中的每一行都用逗号替换了单个空格。指定“\s+”时这对我来说似乎很奇怪? @Tom 不,这是意料之中的,+ 是“一个或多个”,我实际上没有看到“两个或多个”的要求... @Tom 我已更新为“两个或更多”空白。这也意味着tr 解决方案不起作用。

以上是关于使用 sed 将 \s+ 分隔文件转换为 csv的主要内容,如果未能解决你的问题,请参考以下文章

sed 替换字符制表符分隔的 csv

使用 soffice 命令行将 xls 转换为分号分隔的 csv

将列表转换为“受保护的CSV”

使用 C++ 将空格分隔值文本转换为 .csv 然后保存 [关闭]

使用 python 和 pandas 将错误创建的大型 csv 文件转换为制表符分隔文件

如何将同时具有逗号和空格分隔符的 CSV 文件转换为只有空格分隔符的 csv