如何删除字符串中的最后一个分号?

时间:2017-03-01 15:57:56

标签: bash perl awk

我正在使用许多字符串,比如这个结构:

=Cluster=
SPEC    PRD000681;PRIDE_Exp_Complete_Ac_22493.xml;spectrum=4691 true    LHDEEIQELQAQIQEQHVQIDMDVSKPDLTAALR  3940.8833   1   9913        0.9988012901749596
SPEC    PRD000681;PRIDE_Exp_Complete_Ac_22495.xml;spectrum=752  true    LHDEEIQELQAQIQEQHVQIDMDVSKPDLTAALR  3940.8833   1   9913        0.9988012901749596

由于生成文件的程序中存在错误,有时会出现额外的分号,只有一个分号出现在它们不应出现的位置。 例如:

=Cluster=
SPEC    PRD000681;;;;;PRIDE_Exp_Complete_Ac_22493.xml;spectrum=4691 true    LHDEEIQELQAQIQEQHVQIDMDVSKPDLTAALR  3940.8833   1    9913   ;   0.9988012901749596
SPEC    PRD000681;PRIDE_Exp_Complete_Ac_22495.xml;;;;spectrum=752   true    LHDEEIQELQAQIQEQHVQIDMDVSKPDLTAALR  3940.8833   1    9913   ;   0.9988012901749596

为了解决这个问题,我使用正则表达式s/;+/;/g;awk '{gsub(/[;]+/,";")}1'input > output,但我不知道如何删除最后一个分号而不影响第一个分号。

一个好的输出将是这样的:

=Cluster=
SPEC    PRD000681;PRIDE_Exp_Complete_Ac_22493.xml;spectrum=4691 true    LHDEEIQELQAQIQEQHVQIDMDVSKPDLTAALR  3940.8833   1   9913        0.9988012901749596
SPEC    PRD000681;PRIDE_Exp_Complete_Ac_22495.xml;spectrum=752  true    LHDEEIQELQAQIQEQHVQIDMDVSKPDLTAALR  3940.8833   1   9913        0.9988012901749596

我的问题是:如何在不影响第一个分号的情况下删除最后一个分号?

3 个答案:

答案 0 :(得分:6)

使用How do I replace the last occurrence of a character in a string using sed?,您可以说:

sed -r 's/(.*);/\1/' file

也就是说,将所有内容与.*匹配,直到找到最后一个;。这是有效的,因为sed非常贪婪,并且会在找到最后一个;之前啜饮所有内容。

与您的初始表达一起,您将拥有:

sed -re 's/;+/;/g' -e 's/(.*);/\1/' file

由于您的输入文件包含如此多的数据,因此很难看到输出。用一些虚拟数据看到它:

$ cat file
hello;;;;;how;are;you
i;am;fine

只需删除最后一个分号:

$ sed -r 's/(.*);/\1/' file
hello;;;;;how;areyou
i;amfine

移除最后一个半冒号并挤压多个半冒号:

$ sed -re 's/;+/;/g' -e 's/(.*);/\1/' file
hello;how;areyou
i;amfine

答案 1 :(得分:3)

在Perl中

perl -i -pe 's/.*\K;//' myfile

答案 2 :(得分:1)

使用rev和awk(和@ fedorqui的例子):

$ rev file | awk '{ sub(/;/, "") }1' | rev
hello;;;;;how;areyou
i;amfine

使用rev来撤销记录,再次删除带有;的第一个subrev个记录。您可以先使用gsub将多个;替换为:

$ rev file | awk '{ gsub(/\;+/, ";"); sub(/;/, "") }1' | rev
hello;how;areyou
i;amfine