简体   繁体   中英

How to delete everything in a string after a specific character?

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?

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

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.


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 :

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:

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.

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

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

If TEXT contains your text, as in

TEXT=beforexafter

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

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*}" .

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM