I want to do some si开发者_运维知识库mple string replace in Bash with sed. I am Ubuntu 10.10.
Just see the following code, it is self-explanatory:
name="A%20Google.."
echo $name|sed 's/\%20/_/'|sed 's/\.+/_/'
I want to get A_Google_
but I get A_Google..
The sed 's/\.+/_/'
part is obviously wrong.
BTW, sed 's/\%20/_/'
and sed 's/%20/_/'
both work. Which is better?
sed
speaks POSIX basic regular expressions, which don't include +
as a metacharacter. Portably, rewrite to use *
:
sed 's/\.\.*/_/'
or if all you will ever care about 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
That last example answers your other question: a character which is literal when used as is may take on a special meaning when backslashed, and even though at the moment %
doesn't have a special meaning when backslashed, future-proofing means not assuming that \%
is safe.
Additional note: you don't need two separate sed
commands in the pipeline there.
echo $name | sed -e 's/\%20/_/' -e 's/\.+/_/'
(Also, do you only need to do that once per line, or for all occurrences? You may want the /g
modifier.)
The sed
command doesn't understand +
so you'll have to expand it by hand:
sed 's/\.\.*/_/'
Or tell sed
that you want to use extended regexes:
sed -r 's/\.+/_/' # GNU
sed -E 's/\.+/_/' # OSX
Which switch, -r
or -E
, depends on your sed
and it might not even support extended regexes so the portable solution is to use \.\.*
in place of \.+
. But, since you're on Linux, you should have GNU sed
so sed -r
should do the trick.
精彩评论