使用 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的主要内容,如果未能解决你的问题,请参考以下文章
使用 soffice 命令行将 xls 转换为分号分隔的 csv
使用 C++ 将空格分隔值文本转换为 .csv 然后保存 [关闭]