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

时间:2021-08-03 20:07:20

Example:

例:

    before: text_before_specific_character(specific_character)text_to_be_deleted
    after: text_before_specific_character

I know that it can be done with 'sed'. But i'm stuck. Can someone help me out?

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

3 个解决方案

#1


23  

There's no reason to use an external tool such as sed for this; bash can do it internally, using parameter expansion:

为此,没有理由使用像sed这样的外部工具; bash可以使用参数扩展在内部完成:

If the character you want to trim after is :, for instance:

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

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

You can do this in both greedy and non-greedy ways:

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

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

Especially if you're calling this inside a tight loop, starting a new sed process, writing into the process, reading its output, and waiting for it to exit (to reap its PID) can be substantial overhead that doing all your processing internal to bash won't have.

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


Now -- often, when wanting to do this, what you might really want is to split a variable into fields, which is better done with read.

现在 - 通常,当想要这样做时,您可能真正想要的是将变量拆分为字段,最好通过读取来完成。

For instance, let's say that you're reading a line from /etc/passwd:

例如,假设您正在读取/ 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"

Even if you want to process multiple lines from a file, this too can be done with bash alone and no external processes:

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

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

...will emit everything up to the first : from each line of file, without requiring any external tools to be launched.

...将从第一行发出所有内容:从每行文件中,无需启动任何外部工具。

#2


8  

What you're looking for is actually really easy:

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

sed 's/A.*//'

Where A marks the specific character. Note that it is case sensitive, if you want to catch multiple characters use

A标记特定字符。请注意,如果要捕获多个字符,则区分大小写

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

#3


2  

If TEXT contains your text, as in

如果TEXT包含您的文本,请参阅

TEXT=beforexafter

and the specific character happens (for example) to be x, then

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

echo "${TEXT%x*}"

does what you want.

做你想要的。

To Bash, "$TEXT" or "${TEXT}" is the whole beforexafter, but "${TEXT%xafter}" is just before, with the xafter chopped off the end. To chop off the x and anything that might follow it, one writes "${TEXT%x*}".

对于Bash,“$ TEXT”或“$ {TEXT}”是之前的整体,但是“$ {TEXT%xafter}”就在之前,xafter被砍掉了。要切断x及其后可能出现的任何内容,可写入“$ {TEXT%x *}”。

There is also "${TEXT%%x*}", incidentally. This differs from the other only if there is more than one x. With the %%, Bash chops off all x, whereas with the % it chops off only from the last x. You can remember this by observing loosely that the longer %% chops off more text.

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

You can do likewise with Sed, of course, if you prefer:

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

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

#1


23  

There's no reason to use an external tool such as sed for this; bash can do it internally, using parameter expansion:

为此,没有理由使用像sed这样的外部工具; bash可以使用参数扩展在内部完成:

If the character you want to trim after is :, for instance:

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

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

You can do this in both greedy and non-greedy ways:

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

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

Especially if you're calling this inside a tight loop, starting a new sed process, writing into the process, reading its output, and waiting for it to exit (to reap its PID) can be substantial overhead that doing all your processing internal to bash won't have.

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


Now -- often, when wanting to do this, what you might really want is to split a variable into fields, which is better done with read.

现在 - 通常,当想要这样做时,您可能真正想要的是将变量拆分为字段,最好通过读取来完成。

For instance, let's say that you're reading a line from /etc/passwd:

例如,假设您正在读取/ 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"

Even if you want to process multiple lines from a file, this too can be done with bash alone and no external processes:

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

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

...will emit everything up to the first : from each line of file, without requiring any external tools to be launched.

...将从第一行发出所有内容:从每行文件中,无需启动任何外部工具。

#2


8  

What you're looking for is actually really easy:

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

sed 's/A.*//'

Where A marks the specific character. Note that it is case sensitive, if you want to catch multiple characters use

A标记特定字符。请注意,如果要捕获多个字符,则区分大小写

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

#3


2  

If TEXT contains your text, as in

如果TEXT包含您的文本,请参阅

TEXT=beforexafter

and the specific character happens (for example) to be x, then

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

echo "${TEXT%x*}"

does what you want.

做你想要的。

To Bash, "$TEXT" or "${TEXT}" is the whole beforexafter, but "${TEXT%xafter}" is just before, with the xafter chopped off the end. To chop off the x and anything that might follow it, one writes "${TEXT%x*}".

对于Bash,“$ TEXT”或“$ {TEXT}”是之前的整体,但是“$ {TEXT%xafter}”就在之前,xafter被砍掉了。要切断x及其后可能出现的任何内容,可写入“$ {TEXT%x *}”。

There is also "${TEXT%%x*}", incidentally. This differs from the other only if there is more than one x. With the %%, Bash chops off all x, whereas with the % it chops off only from the last x. You can remember this by observing loosely that the longer %% chops off more text.

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

You can do likewise with Sed, of course, if you prefer:

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

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