如何在特定字符后删除字符串中的所有内容?

时间:2012-06-29 16:15:20

标签: linux bash

示例:

    before: text_before_specific_character(specific_character)text_to_be_deleted
    after: text_before_specific_character

我知道可以用'sed'完成。但我被卡住了。有人可以帮助我吗?

3 个答案:

答案 0 :(得分:25)

没有理由使用像sed这样的外部工具; bash可以在内部完成,using parameter expansion

如果你要修剪的角色是:,例如:

$ str=foo_bar:baz
$ echo "${str%%:*}"
foo_bar

你可以用贪婪和非贪婪的方式做到这一点:

$ str=foo_bar:baz:qux
$ echo "${str%:*}"
foo_bar:baz
$ echo "${str%%:*}"
foo_bar

特别是如果你在一个紧密的循环中调用它,启动一个新的sed进程,写入进程,读取它的输出,并等待它退出(以获得它的PID)可能是一个很大的开销,所有你的处理bash内部的处理将不会。


现在 - 通常,当您想要这样做时,您可能真正想要的是将变量拆分为字段,最好使用read

例如,假设您正在阅读/etc/passwd中的一行:

line=root:x:0:0:root:/root:/bin/bash
IFS=: read -r name password_hashed uid gid fullname homedir shell _ <<<"$line"
echo "$name" # will emit "root"
echo "$shell" # will emit "/bin/bash"

即使您想要处理文件中的多行,也可以单独使用bash而不需要外部进程:

while read -r; do
  echo "${REPLY%%:*}"
done <file

...会从:的每一行发出最后一个file的内容,而无需启动任何外部工具。

答案 1 :(得分:10)

您所寻找的实际上非常简单:

sed 's/A.*//'

A标记特定字符的位置。请注意,它区分大小写,如果要捕获多个字符,请使用

sed 's/[aAbB].*//'

答案 2 :(得分:2)

如果TEXT包含您的文字,例如

TEXT=beforexafter

并且特定字符发生(例如)为x,然后

echo "${TEXT%x*}"

做你想做的事。

要Bash,"$TEXT""${TEXT}"是整个beforexafter,但"${TEXT%xafter}"只是beforexafter被切断了结束。要切断x以及可能跟随它的任何内容,可以写"${TEXT%x*}"

顺便提一句,还有"${TEXT%%x*}"。仅当存在多个x时,这与另一个不同。使用%%时,Bash会删除所有x,而使用%时,它只会从上一个x中删除。您可以通过松散地观察较长的%%来删除更多文本来记住这一点。

当然,如果你愿意,你可以用Sed做同样的事情:

echo "$TEXT" | sed 's/x.*//'