如何在整个系统中进行查找和替换?

时间:2014-08-23 06:12:13

标签: regex linux bash sed grep

我想运行一个查询或脚本,首先搜索我系统上的每个.php文件,查找字符串strawberry。如果在任何地方找到该字符串,则包含它的整行应替换为字符串pineapple。我只能访问bash,没有Ruby / Python /更灵活的语言。

我确信有办法做到这一点,但我无法弄明白。我甚至无法找出启动它的grep命令... grep -Rl "strawberry" .似乎返回目录中的每个文件,甚至那些根本不包含字符串'strawberry'的文件。

3 个答案:

答案 0 :(得分:2)

你并不是真的想要,而且可能无处可到。

find / -type f -name '*.php' -exec sed -i 's/.*strawberry.*/pineapple/' {} \;

如果您正在尝试清除恶意软件感染或闯入,正确的做法是让您的网站脱机,修复攻击媒介,强化您的系统,审核脚本并恢复其余部分来自已知良好的备份

答案 1 :(得分:0)

这个怎么样?

grep -RlZ "strawberry" /srv/www | 
    grep -z '.*\.php$' |
    xargs -r -0 sed -i 's|.*strawberry.*|pineapple|'

为了解释一下,使用以下选项调用管道的第一个grep(1)调用:

  • -R:在任何符号链接之后递归目录。请注意与-r的区别。
  • -l:输出任何匹配的文件名。
  • -Z:后缀任何带有零字节的输出文件名。这用于确保正确处理具有空格等的名称。
  • /srv/www是要搜索的目录层次结构顶部的路径。您应该避免在此使用/ - 您可能不想这样做,尤其是如果您使用root权限执行此操作。

第二个grep过滤掉任何非PHP文件。 -z选项指示它使用零字节作为行(即文件名)分隔符而不是换行符。

最后一部分使用xargs(1)执行sed(1)

  • 如果找不到匹配的文件,-r的{​​{1}}选项只会出现错误。
  • xargs的{​​{1}}选项让它知道输入项以零字节分隔。
  • -0的{​​{1}}选项指示其执行匹配文件的就地替换。
  • 最后,替换表达式xargs翻译为"任何字符串,后跟 strawberry ,后跟任何字符串应替换为字符串 pineapple "

然而,这不是执行此搜索的最有效方式 - 第一个-i将很乐意搜索每个文件,而不仅仅是PHP文件。更有效的方法是使用find(1)预先过滤文件名:

sed

请注意s|.*strawberry.*|pineapple| / grep部分 - 它用于阻止包含搜索字符串的文件通过find -L /srv/www -type f -name '*.php' -print0 | xargs -r -0 grep -lZ "strawberry" | xargs -r -0 sed -i 's|.*strawberry.*|pineapple|' 进行过滤,如这至少会改变他们的修改时间并可能产生其他问题。作为一项原则,在发出递归命令时总是尽可能具体[/ em> ...

我把剩下的解释作为练习留给读者: - )

答案 2 :(得分:0)

如果您使用的是gawk4.1,则可以inplace extension使用bash的{​​{1}}选项进行递归搜索。

globstar