我正在创建一个脚本,它将字符串作为参数并在目录中递归替换。简单的案例(一个单词)由以下查找和替换脚本令人钦佩地处理:
grep -rl $1 . | xargs sed -i .backup -e "s/$1/$2/g"
但是这里的事情变得有点棘手。我试图处理的字符串是一个恶意软件脚本,它感染了我写的网站(但没有托管):
<iframe src="http://reycross.cn/qaqa/" width=0 height=0 style="hidden" frameborder=0 marginheight=0 marginwidth=0 scrolling=no></iframe>
对于bash和sed来说,这个字符串显然很复杂,需要一些转义。我已经尝试过rpl,一种特殊用途的替换工具,但它不能很好地处理空白:
rpl -pR $* '' *
然而,在提示符下,我能够用字符串替换$ *并获得预期的行为。关于如何将bash,sed或rpl变成可爱的remove-long-string.sh的任何想法?
答案 0 :(得分:1)
这是因为bash使用$ *
在每个空格处拆分每个参数尝试以下方法:
rpl -pR "$@" '' *
答案 1 :(得分:1)
不,该字符串实际上不需要任何转义:)。
var='<iframe src="http://reycross.cn/qaqa/" width=0 height=0 style="hidden" frameborder=0 marginheight=0 marginwidth=0 scrolling=no></iframe>'
echo "$var" | grep -v "$var" # prints nothing
echo "$var" | sed "s#$var#complete match#" # prints "complete match"
如果您需要使用任意数量的任何特殊字符的通用字符串,那么您将需要以与未转义的相反的顺序对其进行转义。
如果是sed,它一次用于bash,一次用于sed的regexp。
可以通过
绕过Bashvar="$(cat file_with_search_string)"
对于sed,你需要首先转义反斜杠,然后是sed border character(上例中为#)和所有正则表达式控件 - ^ $ []。* +?等等。
var="${var//\\/\\\\}"
var="${var//#/\\#}"
var="${var//[/\\[}"
# ...
# I'm sure this can somehow be converted into tr script
grep -rl $1 . | xargs sed -i .backup "s#$var#here be dragons#g"
答案 2 :(得分:-2)
我不知道rpl
,但如果引用第一个参数,它会有帮助吗?那会传递整个字符串,空格和所有,作为一个参数。如果没有引号,shell会将其拆分为多个参数。
rpl -pR "$@" '' *
或
rpl -pR "$1" "$2" *