Sed:用一个下划线替换一系列点

时间:2011-07-09 22:32:51

标签: linux bash command-line sed

我想用sed在Bash中做一些简单的字符串替换。我是Ubuntu 10.10。

只需看下面的代码,它就是不言自明的:


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

我想获得A_Google_,但我得到A_Google..

sed 's/\.+/_/'部分显然是错误的。

BTW,sed 's/\%20/_/'sed 's/%20/_/'都有效。哪个更好?

2 个答案:

答案 0 :(得分:5)

sed说POSIX基本正则表达式,它不包含+作为元字符。可以移植,重写使用*

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

或者如果您只关心Linux,您可以使用各种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

最后一个例子回答了你的另一个问题:一个字符在按原样使用时字面意思在反向时可能具有特殊意义,即使目前 %没有&#39 ; t在反向时具有特殊含义,面向未来意味着不假设\%是安全的。

附加说明:您不需要在管道中使用两个单独的sed命令。

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

(另外,你只需要每行一次,或者所有事件都这样做吗?你可能需要/g修饰符。)

答案 1 :(得分:2)

sed命令无法理解+,因此您必须手动展开它:

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

或告诉sed您要使用扩展正则表达式:

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

哪个开关-r-E取决于您的sed,它甚至可能不支持扩展的正则表达式,因此便携式解决方案是使用\.\.*代替{ {1}}。但是,既然你在Linux上,那么你应该有GNU \.+,所以sed可以做到这一点。