我有一个两列、空格分隔的 .txt 文件,但第一列有空格(这是错误)。我需要将其转换为 csv,但我不能直接用逗号替换所有空格。
输入示例:
gi|118592783|ref|ZP_01550172.1|_biphenyl-2 3-diol_1 2-dioxygenase_[Stappia_aggregata_IAM_12614] 1
期望输出:
gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1
我如何使用sed
(或其他任何方法)将一行中的最后一个空格替换为逗号,然后删除所有剩余空格?这样能有效地创建一个 CSV 文件吗?
答案1
就像是:
sed -r 's/(.*) /\1,/; s/ //g'
第一个替换是贪婪的,它将覆盖组中除最后一个空格之外的所有空格,将最后一个空格替换为,
。第二个替换将消除其余部分。
答案2
这将完成这项工作:
sed -r "s/\s([0-9]+$)/,\1/" filename.txt | tr -d ' '
或者:
sed -r "s/\s([0-9]+$)/,\1/; s/\s//g" filename.txt
输入示例:
gi|118592783|ref|ZP_01550172.1|_biphenyl-2 3-diol_1 2-dioxygenase_[Stappia_aggregata_IAM_12614] 1
输出:
gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1
答案3
这是一个奇怪的方法——使用 sed 循环。
- 如果模式仅包含一个空格,则将其替换为逗号
- (否则)用空替换第一个空格并转到 1
我们可以在 GNU sed 中将其写为
sed -e :1 -e '/^[^ ]* [^ ]*$/ s/ /,/' -e 's/ //; t1'
测试:
$ echo 'gi|118592783|ref|ZP_01550172.1|_biphenyl-2 3-diol_1 2-dioxygenase_[Stappia_aggregata_IAM_12614] 1' |
sed -e :1 -e '/^[^ ]* [^ ]*$/ s/ /,/' -e 's/ //; t1'
gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1
答案4
Perl
$ perl -ne 's/\s//g;s/^(.*)([[:digit:]])$/\1,\2/;print' input.txt
gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1
或更短:
perl -pe 's/\s//g;s/^(.*)([[:digit:]])$/\1,\2/' input.txt
实际上,这与 muru 的方法正好相反:我们首先删除所有空格,然后将最后一个项目(group \1
)和最后一个项目(group \2
,两个恰好是数字)之前的所有内容分组。我们用 group 替换行\1
,并\2
用逗号分隔。
请注意,如果有必要,([[:digit:]])
可以将其改为引用任何字符(即,如果我们期望最后一个字符是任何类型),或者我们可以用来处理仅可打印的字符(.)
([[:graph:]])