Sed: replace a series of dots with one underline

I want to make a simple string replacement in Bash using sed. I am Ubuntu 10.10.

Just review the following code, this is self-evident:

name="A%20Google.." echo $name|sed 's/\%20/_/'|sed 's/\.+/_/' 

I want to get A_Google_ , but I get A_Google..

The sed 's/\.+/_/' is obviously incorrect.

BTW, sed 's/\%20/_/' and sed 's/%20/_/' work. What's better?

+4
source share
2 answers

sed says basic POSIX regular expressions that do not include + as a metacharacter. In portable mode, rewrite to use * :

 sed 's/\.\.*/_/' 

or if all you ever need is Linux, you can use various GNU-isms:

 sed -r 's/\.\.*/_/' # turn on POSIX EREs (use -E instead of -r on OS X) sed 's/\.\+/_/' # GNU regexes invert behavior when backslash added/removed 

This last example answers your other question: a character that is literal when used can have special meaning when flipping back, and although % doesn't really matter when flipping back, which means that \% is safe.

Note: you do not need two separate sed commands.

 echo $name | sed -e 's/\%20/_/' -e 's/\.+/_/' 

(Also, you only need to do this once per line or for all occurrences? You may need the /g modifier.)

+5
source

The sed command does not understand + , so you have to deploy it manually:

 sed 's/\.\.*/_/' 

Or tell sed that you want to use extended regular expressions:

 sed -r 's/\.+/_/' # GNU sed -E 's/\.+/_/' # OSX 

Which switch, -r or -E , depends on your sed , and it may not even support extended regular expressions, so the portable solution should use \.\.* Instead of \.+ . But since you are on Linux, you must have GNU sed , so sed -r should do the trick.

+2
source

All Articles