使用sed或其他bash工具移除字符串末尾的模式

28

我想删除字符串末尾的任何ABC。

我能想到的最好方法是

echo ${String}| sed -e 's/["ABC"]*$//g'

然而,它将删除字符串末尾的所有A、B或C。

如果字符串为DAAAAABCBBBCCABCABC,如果我使用上述表达式,它将返回"D",而不是"DAAAAABCBBBCC"。

有没有更好的方法来做到这一点?谢谢。

3个回答

32

bash 可以在内部完成此操作。以下命令可以删除任何位于结尾的 "ABC" 字符串,并且其结果可以用于变量赋值、命令等等:

```bash

str="this is ABC"

result="${str%%ABC}"

echo "$result"

```

${String%ABC}

您也可以使用正则表达式而不仅仅是简单的字符串匹配。请参见http://tldp.org/LDP/abs/html/string-manipulation.html


1
这只会删除最后一次出现的 ABC。这种Shell参数扩展使用glob,因此无法用它来表示“任意数量的ABC”。更多信息:http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion - Maic López Sáenz
1
使用扩展通配符(shopt -s extglob),@LopSae 的代码可以正常工作:${String%%+(ABC)} - Benjamin W.
能否在其中放置正则表达式? - Jerry Green
是的,请查看链接。我已相应地编辑了答案。谢谢! - mabraham
那其实不是正则表达式,而是一种bash全局匹配模式。 - tony19
是的,我的例子是一个模式匹配。然后我说也可以使用正则表达式。我没有把我的例子称为正则表达式。 :-) - mabraham

29

这个应该可以工作:

echo "DAAAAABCBBBCCABCABC" | sed -e 's/\(ABC\)*$//g'

结果:

DAAAAABCBBBCC

将字符串用括号括起来,* 应用于括号内的所有字母,并且按照精确顺序应用。


为什么 sed -e 's/\(;;\)*$//g' foo.csv 无法删除行尾的 ;;?例如,我有一行 County;4;5;0;20;4;5;4;5;;,输出结果仍然相同。 - Sigur
@Sigur:对我来说有效。检查一下末尾是否有空白字符。 - Birei
1
我发现了问题。它是行尾字符。它已经解决了。 - Sigur

6

您应该使用:

sed -E 's/(ABC)+$//'

或者:

sed -r 's/(ABC)+$//'

两者都会输出:

DAAAAABCBBBCC

1
值得一提的是,这两个参数都允许将表达式解释为扩展正则表达式。我曾经看到Mac(Darwin)使用了“-E”,而其他Linux发行版使用了“-r”。 - Maic López Sáenz
1
“-E”是为了与BSD sed兼容而未记录的选项。您几乎肯定应该使用“-r”。在busybox版本的sed上,“-E”将失败。 - Six
1
多年来我一直使用基本的sed,但我对为什么 sed -e 's/^[0-9]+//' 不起作用感到困惑。通常十年前的技术答案已经过时了,但这个不是。谢谢! - Jim
1
多年来我一直使用基本的sed命令,但是我对于sed -e 's/^[0-9]+//'为什么不起作用感到困惑。通常十年前的技术答案已经过时了,但这个答案却没有。谢谢! - Jim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接