开发者

Sed:Replace a series of dots with one underscore

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜