在我的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是一个哑子字符串,没有匹配等。不是用户提供的。
当前回答
如果您只是想替换sed命令中的变量值,那么只需删除 例子:
sed -i 's/dev-/dev-$ENV/g' test to sed -i s/dev-/dev-$ENV/g test
其他回答
下面是我之前用过的一个AWK的例子。它是一个AWK,打印新的AWKS。AWK和SED相似,可能是一个很好的模板。
ls | awk '{ print "awk " "'"'"'" " {print $1,$2,$3} " "'"'"'" " " $1 ".old_ext > " $1 ".new_ext" }' > for_the_birds
这看起来有点过分,但不知何故,引号的组合可以保持“打印为字面量”。然后,如果我没记错的话,变量只是用引号括起来:“$1”。试试吧,让我知道它对SED的效果如何。
替换子句中只有三个特殊处理的文字字符是/(关闭子句)、\(转义字符、反向引用和&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的参数
rpstring="s/KEYWORD/$REPLACE/g"
sed -i $rpstring test.txt
看来你问错问题了。我也问错了问题。错误的原因是第一句话的开头:“在我的bash脚本中…”。
我也有同样的问题,犯了同样的错误。如果您正在使用bash,则不需要使用sed来进行字符串替换(使用bash中内置的替换特性要干净得多)。
而不是像这样,例如:
function escape-all-funny-characters() { UNKNOWN_CODE_THAT_ANSWERS_THE_QUESTION_YOU_ASKED; }
INPUT='some long string with KEYWORD that need replacing KEYWORD.'
A="$(escape-all-funny-characters 'KEYWORD')"
B="$(escape-all-funny-characters '<funny characters here>')"
OUTPUT="$(sed "s/$A/$B/g" <<<"$INPUT")"
你可以专门使用bash特性:
INPUT='some long string with KEYWORD that need replacing KEYWORD.'
A='KEYWORD'
B='<funny characters here>'
OUTPUT="${INPUT//"$A"/"$B"}"
如果您正在生成一个随机密码以传递给sed替换模式,那么您应该注意随机字符串中的哪一组字符。如果您选择一个由base64编码的值组成的密码,那么在base64中只有一个字符是可能的,而且在sed replace模式中也是一个特殊字符。这个字符是“/”,很容易从你生成的密码中删除:
# password 32 characters log, minus any copies of the "/" character.
pass=`openssl rand -base64 32 | sed -e 's/\///g'`;