16

例子:

    before: text_before_specific_character(specific_character)text_to_be_deleted
    after: text_before_specific_character

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

4

3 回答 3

30

没有理由为此使用 sed 之类的外部工具。bash 可以在内部使用参数扩展

如果要修剪的字符是:,例如:

$ 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,而无需启动任何外部工具。

于 2012-06-29T16:23:16.690 回答
11

你要找的其实很简单:

sed 's/A.*//'

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

sed 's/[aAbB].*//'
于 2012-06-29T16:21:06.717 回答
2

如果 TEXT 包含您的文本,如

TEXT=beforexafter

并且特定字符恰好(例如)是x,然后

echo "${TEXT%x*}"

做你想做的事。

To Bash, "$TEXT"or "${TEXT}"is the whole beforexafter, but "${TEXT%xafter}"is just before, with the xaftercut off end 。为了砍掉它x和任何可能跟随它的东西,一个人写道"${TEXT%x*}"

还有"${TEXT%%x*}",顺便说一句。仅当存在多个 时,它才与另一个不同x。使用%%, Bash 砍掉所有x,而使用%it 仅从最后一个砍掉x。您可以通过松散地观察更长的%%文本来记住这一点。

当然,如果您愿意,您也可以对 Sed 进行同样的操作:

echo "$TEXT" | sed 's/x.*//'
于 2012-06-29T16:32:33.863 回答