在我的bash脚本中,我有一个外部(从用户接收)字符串,我应该在sed模式中使用。
REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"
我如何转义$REPLACE字符串,以便它被sed安全地接受为文字替换?
注意:KEYWORD是一个哑子字符串,没有匹配等。不是用户提供的。
在我的bash脚本中,我有一个外部(从用户接收)字符串,我应该在sed模式中使用。
REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"
我如何转义$REPLACE字符串,以便它被sed安全地接受为文字替换?
注意:KEYWORD是一个哑子字符串,没有匹配等。不是用户提供的。
当前回答
基于钢琴龙的正则表达式,我做了一个bash函数,逃脱关键字和替换。
function sedeasy {
sed -i "s/$(echo $1 | sed -e 's/\([[\/.*]\|\]\)/\\&/g')/$(echo $2 | sed -e 's/[\/&]/\\&/g')/g" $3
}
下面是如何使用它:
sedeasy "include /etc/nginx/conf.d/*" "include /apps/*/conf/nginx.conf" /etc/nginx/nginx.conf
其他回答
下面是我之前用过的一个AWK的例子。它是一个AWK,打印新的AWKS。AWK和SED相似,可能是一个很好的模板。
ls | awk '{ print "awk " "'"'"'" " {print $1,$2,$3} " "'"'"'" " " $1 ".old_ext > " $1 ".new_ext" }' > for_the_birds
这看起来有点过分,但不知何故,引号的组合可以保持“打印为字面量”。然后,如果我没记错的话,变量只是用引号括起来:“$1”。试试吧,让我知道它对SED的效果如何。
基于钢琴龙的正则表达式,我做了一个bash函数,逃脱关键字和替换。
function sedeasy {
sed -i "s/$(echo $1 | sed -e 's/\([[\/.*]\|\]\)/\\&/g')/$(echo $2 | sed -e 's/[\/&]/\\&/g')/g" $3
}
下面是如何使用它:
sedeasy "include /etc/nginx/conf.d/*" "include /apps/*/conf/nginx.conf" /etc/nginx/nginx.conf
以下是我找到的转义码:
* = \x2a
( = \x28
) = \x29
" = \x22
/ = \x2f
\ = \x5c
' = \x27
? = \x3f
% = \x25
^ = \x5e
替换子句中只有三个特殊处理的文字字符是/(关闭子句)、\(转义字符、反向引用和&c.)和&(在替换中包含匹配)。因此,你所需要做的就是转义这三个字符:
sed "s/KEYWORD/$(echo $REPLACE | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g')/g"
例子:
$ export REPLACE="'\"|\\/><&!"
$ echo fooKEYWORDbar | sed "s/KEYWORD/$(echo $REPLACE | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g')/g"
foo'"|\/><&!bar
sed命令允许你使用其他字符代替/作为分隔符:
sed 's#"http://www\.fubar\.com"#URL_FUBAR#g'
双引号不是问题。