本文翻译自:Escape a string for a sed replace pattern
In my bash script I have an external (received from user) string, which I should use in sed pattern. 在我的bash脚本中,我有一个外部(从用户那里收到的)字符串,我应该在sed模式中使用它。
REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"
How can I escape the $REPLACE
string so it would be safely accepted by sed
as a literal replacement? 如何才能转义$REPLACE
字符串,以便sed
安全地接受它作为文字替换?
NOTE: The KEYWORD
is a dumb substring with no matches etc. It is not supplied by user. 注意: KEYWORD
是一个哑子字符串,没有匹配项等。它不是用户提供的。
#1楼
参考:https://stackoom.com/question/1i0x/转义sed替换模式的字符串
#2楼
Based on Pianosaurus's regular expressions, I made a bash function that escapes both keyword and replacement. 基于Pianosaurus的正则表达式,我制作了一个bash函数,该函数同时避免了关键字和替换。
function sedeasy {
sed -i "s/$(echo $1 | sed -e 's/\([[\/.*]\|\]\)/\\&/g')/$(echo $2 | sed -e 's/[\/&]/\\&/g')/g" $3
}
Here's how you use it: 使用方法如下:
sedeasy "include /etc/nginx/conf.d/*" "include /apps/*/conf/nginx.conf" /etc/nginx/nginx.conf
#3楼
don't forget all the pleasure that occur with the shell limitation around " and ' 不要忘记围绕“和”的shell限制所带来的所有乐趣。
so (in ksh) 所以(以ksh为单位)
Var=">New version of \"content' here <"
printf "%s" "${Var}" | sed "s/[&\/\\\\*\\"']/\\&/g' | read -r EscVar
echo "Here is your \"text\" to change" | sed "s/text/${EscVar}/g"
#4楼
It's a bit late to respond... but there IS a much simpler way to do this. 做出响应有点晚了...但是有一种更简单的方法可以执行此操作。 Just change the delimiter (ie, the character that separates fields). 只需更改定界符(即,分隔字段的字符)。 So, instead of s/foo/bar/
you write s|bar|foo
. 因此,代替s/foo/bar/
,而是编写s|bar|foo
。
And, here's the easy way to do this: 而且,这是执行此操作的简单方法:
sed 's|/\*!50017 DEFINER=`snafu`@`localhost`\*/||g'
The resulting output is devoid of that nasty DEFINER clause. 结果输出没有讨厌的DEFINER子句。
#5楼
Use awk - it is cleaner: 使用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
#6楼
Warning : This does not consider newlines. 警告 : 不考虑换行。 For a more in-depth answer, see this SO-question instead. 有关更深入的答案,请参阅此SO问题 。 (Thanks, Ed Morton & Niklas Peter) (感谢Ed Morton和Niklas Peter)
Note that escaping everything is a bad idea. 请注意,转义所有内容不是一个好主意。 Sed needs many characters to be escaped to get their special meaning. Sed需要转义许多字符才能获得其特殊含义。 For example, if you escape a digit in the replacement string, it will turn in to a backreference. 例如,如果您在替换字符串中转义了一个数字,它将变成反向引用。
As Ben Blank said, there are only three characters that need to be escaped in the replacement string (escapes themselves, forward slash for end of statement and & for replace all): 正如本·布兰克(Ben Blank)所说,替换字符串中只需要转义三个字符(转义自身,语句末尾用正斜杠和&替换所有字符):
sed -e 's/[\/&]/\\&/g'
If you ever need to escape the KEYWORD
string, the following is the one you need: 如果您需要转义KEYWORD
字符串,则需要以下内容:
sed -e 's/[]\/$*.^[]/\\&/g'
Remember, if you use a character other than /
as delimiter, you need replace the slash in the expressions above wih the character you are using. 请记住,如果您使用/
以外的其他字符作为分隔符,则需要在上面使用该字符的表达式中替换斜杠。 See PeterJCLaw's comment for explanation. 请参阅PeterJCLaw的注释以获取解释。
Edited: Due to some corner cases previously not accounted for, the commands above have changed several times. 编辑:由于以前没有考虑某些极端情况,因此上面的命令已更改了几次。 Check the edit history for details. 查看编辑历史记录以了解详细信息。