在我的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是一个哑子字符串,没有匹配等。不是用户提供的。
当前回答
我有一个改进sedeasy功能,这将打破特殊字符,如制表符。
function sedeasy_improved {
sed -i "s/$(
echo "$1" | sed -e 's/\([[\/.*]\|\]\)/\\&/g'
| sed -e 's:\t:\\t:g'
)/$(
echo "$2" | sed -e 's/[\/&]/\\&/g'
| sed -e 's:\t:\\t:g'
)/g" "$3"
}
那么,有什么不同呢?$1和$2用引号括起来,以避免shell展开并保留制表符或双空格。
附加管道| sed -e 's:\t:\\t:g'(我喜欢:as令牌)转换\t中的制表符。
其他回答
使用awk -它更干净:
$ awk -v R='//addr:\\file' '{ sub("THIS", R, $0); print $0 }' <<< "http://file:\_THIS_/path/to/a/file\\is\\\a\\ nightmare"
http://file:\_//addr:\file_/path/to/a/file\\is\\\a\\ nightmare
如果您正在生成一个随机密码以传递给sed替换模式,那么您应该注意随机字符串中的哪一组字符。如果您选择一个由base64编码的值组成的密码,那么在base64中只有一个字符是可能的,而且在sed replace模式中也是一个特殊字符。这个字符是“/”,很容易从你生成的密码中删除:
# password 32 characters log, minus any copies of the "/" character.
pass=`openssl rand -base64 32 | sed -e 's/\///g'`;
基于钢琴龙的正则表达式,我做了一个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
现在回复有点晚了……但有一种更简单的方法。只需更改分隔符(即分隔字段的字符)。所以不是s/foo/bar/而是s|bar|foo。
这里有一个简单的方法:
sed 's|/\*!50017 DEFINER=`snafu`@`localhost`\*/||g'
结果输出没有那个讨厌的DEFINER子句。
以下是我找到的转义码:
* = \x2a
( = \x28
) = \x29
" = \x22
/ = \x2f
\ = \x5c
' = \x27
? = \x3f
% = \x25
^ = \x5e