【问题标题】:find and replace using grep inside jpg files在 jpg 文件中使用 grep 查找和替换
【发布时间】:2012-02-29 23:19:43
【问题描述】:

我一直在努力解决 grep 问题,试图在我的服务器上扭转服务器范围的黑客攻击,但是当作为 shell 运行时,grep 似乎无法在 jpg 文件中搜索,但是 grep 命令在 ssh 中它自己的作品文件上。

这会很好地返回结果: grep -l -R "讨厌的代码" /var/www/vhosts

但是当作为 shell 脚本运行时,它不再找到 jpg。

for file in $(grep -l -R "nastycode" /var/www/vhosts)
 do
  sed -e "s/"nastycode"/"nicecode"/ig" $file > /tmp/tempfile.tmp
  mv /tmp/tempfile.tmp $file
  echo "Modified: " $file
 done

问:可能与“for file in”部分有关吗? 问:在我们的搜索模式“nastycode”中,我们可以搜索具有 regexp 字符但将它们视为正常字符($、|?等)的东西吗?

提前致谢。

尼古拉斯

【问题讨论】:

  • 我不确定您所说的“在 jpg 文件中搜索”是什么意思——您的意思是您希望 sed 以某种方式在二进制文件 (.jpg) 中搜索字符串? Re 'nastycode' 是一个文字字符串,而不是正则表达式——你可以使用-F(或--fixed-strings)。
  • 感谢您的回复。当我说“在 JPG 文件中搜索”时,我的意思是黑客已经编辑了 jpg 文件并将 php 代码添加到文件中,但仍然向用户显示 jpg。 (他们还添加了一个 htaccess 文件以将 jpg 处理为 php 并执行代码)
  • 文字似乎不起作用。我正在尝试搜索 ") || stristr(" 并替换为 ") &&false || stristr(" 以使脚本无用
  • 你是说 {grep -l -R "nastycode" /var/www/vhosts} 返回一些 jpg,但是在脚本中运行时,同一行找不到 jpg?我要检查的第一件事是“whcih grep”,以确保您的路径没有改变。
  • 我认为你们帮助我解决了其中一个问题。我现在可以让它从 shell 脚本正确运行。我认为不返回结果的问题来自递归函数没有通过足够的子深度,或者 -F 也失败了

标签: shell ssh grep replace


【解决方案1】:

grep 可以选择忽略特殊字符 (-F),只要没有换行符。不幸的是,sed 没有这样的选择。如果其中有特殊字符,则必须对其进行转义。如果其中有很多 /s,则可以通过更改分隔符来避免转义它们 - s|old|new|s@old@new@,或您的代码不包含的其他字符。关于结构的其余部分,我有几个 cmets。首先,你不应该使用for file in command 结构,它会在空白处中断;请改用**(您可能需要先使用shopt -s globstar 启用它)或find。接下来,GNU sed 有一个内联选项 -i。您还可以为其指定备份后缀(例如,-i.bak)。由于sed 仅在找到模式时才会更改,因此实际上没有理由使用grep 来限制文件。

将所有这些放在一起,(一旦您的正则表达式被转义 - 如果您需要,我们也可以提供帮助)您可以使用这些:

# Globstar
for file in /var/www/vhosts/**; do
    sed -i.bak 's/) || stristr(\$ua/) \&\&false || stristr($ua/ig' $file
done

# find
find /var/www/vhosts -type f -exec sed -i.bak 's/) || stristr(\$ua/) \&\&false || stristr($ua/ig' {} \;

# If you really want the echo notification
find /var/www/vhosts -type f -exec grep -qiF ') || stristr($ua' {} \; -exec sed -i.bak 's/) || stristr(\$ua/) \&\&false || stristr($ua/ig' {} + -printf "Modified %p\n"

【讨论】:

  • 感谢 Kevin,我来自 PHP 背景,不太习惯做这种事情,但由于某种原因,问题已经找到了我的办公桌 :) 我要替换的实际代码是") || stristr($ua",并将其替换为 ") &&false || stristr($ua"。你能帮我转义那个字符串吗?我注意到它也不保留文件的所有权,所以当我们修改文件时,它会将所有权更改为 root。
  • 当我玩你的例子时,我得到错误'find:缺少`-exec'的参数。我正在用一个纯字符串测试它,只是为了在尝试困难的搜索字符串之前理解它。
  • @user1239330 好的,我已经更新了实际的字符串。您只需要在搜索中转义$,在替换中转义&s。请注意,在最后一个示例中,我没有转义 grep 中的 $,因为我给了它 -F 标志。
  • 我发现我错过了{} \;,我已经添加了它。
  • 关于所有权变更,您确定您的所有权实际上是在变更所有权吗?我的测试没有,并且通常命令不会将所有权更改为 root,除非明确要求(创建或chowning 文件)
猜你喜欢
  • 1970-01-01
  • 2014-02-11
  • 2020-11-15
  • 1970-01-01
  • 2021-09-30
  • 2011-09-04
  • 1970-01-01
  • 2011-07-18
相关资源
最近更新 更多