我想用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/_/'
都有效。哪个更好?
答案 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
可以做到这一点。