【问题标题】:Recursively find all php files not starting with a comment递归查找所有不以注释开头的php文件
【发布时间】:2016-11-24 06:21:07
【问题描述】:

是否有任何有用的命令组合(sed/grep/find 等)可用于检测不以注释开头的 .php 文件?我当然可以写一个小脚本,但我宁愿使用 shell 命令。

匹配模式:

<?php
/*

我想搜索文件的内容,而不是文件名。

我必须处理一个代码注入遵循某种模式的被黑网站。

<?php $code....
/*

或

<?php
$code....
/*

【问题讨论】:

  • Get inspired for this solution 下次再给我们更多代码。
  • 我不是搜索文件名。而且我无法提供更多代码,因为我想 grep 所有文件的模式是&lt;?php\n/*
  • 如果您不搜索文件名,您的预期输出是什么?

标签: linux bash shell grep


【解决方案1】:

这将检测所有以 php 标签开头的 php 文件;

find ./ -iname '*.php' | xargs head -v -n 1 | grep -B 1 '<?php'
  • 查找所有带有 php 扩展名的文件。
  • 在第一行开头并包含文件名。
  • grep 此输出以查找任何以 php 标记开头的文件。
  • -B 1:在匹配前保留 1 行,以便我们获取文件名。

这又快又脏,你可以想办法让输出更好或更健壮。

【讨论】:

    【解决方案2】:

    您可以在 shell 中使用这个小 awk 脚本来确定文件是否以注释开头不:

    awk 'NR==2 && f$0!="<?php/*"{print FILENAME}NR>2{exit 1}{f=$0}' file.php
    

    要将脚本递归地应用于目录,请使用:

    find -name '*.php' \
      -exec awk 'NR==2 && f$0!="<?php/*"{print FILENAME}NR>2{exit 1}{f=$0}' {} \;
    

    可能的空格是上述解决方案的一个限制,但可以通过在与&lt;php?/*比较之前删除所有可能的空格来轻松适应它

    【讨论】:

      【解决方案3】:

      awk是你的朋友:

       find /your/path/here -type f -iname "*.php" -exec \
       awk 'FNR==2{if($0~/^\/\*/){print FILENAME};exit}' {} \;
      

      备注

      1. {} 是由find 传递给awk 的参数。
      2. awk builtin FILENAME 包含正在处理的当前文件
      3. $0~/^\/\*/ 在第二行开头搜索/*
      4. FNR==2看起来选择要处理的记录号,exit用于处理完需要的记录后退出awk。

      【讨论】:

        【解决方案4】:

        使用gnu grep,您可以使用此递归搜索:

        grep -rvlz $'^[[:space:]]*<?php\n/\*' --include='*.php'
        

        【讨论】:

        • 我喜欢这种方法,但它没有成功,因为它正在搜索整个文件,并且只返回不包含 any 注释的文件。我只需要搜索前几个字节。
        • 太棒了,正是我想要的。你能解释一下^[[:space:]]*-magic吗?
        • 这是 POSIX 类属性,用于匹配任何空格,包括新行。锚 ^ 确保我们仅在开始时匹配它。
        • @EdMorton:公平点。 -E 这里不需要并被添加为错误。今天早上我使用手机进行了编辑,没有进行测试。现在已经修复了
        【解决方案5】:

        用于查找文件的 UNIX 工具名为 find,用于通用文本操作的 UNIX 工具是 awk:

        find . -name '*.php' -print |
        xargs awk -v RS='^$' 'index($0,"<?php\n/*")==1{print FILENAME}'
        

        以上使用 GNU awk 进行多字符 RS。我们使用 index() 来强制执行字符串而不是 regexp 搜索,因为您的目标字符串包含多个 regexp 元字符,这样我们就可以将它们全部转义。

        【讨论】:

        • 谢谢。 awk 对我来说一直是个谜,但您的解决方案似乎并不完全有效。我不太确定这是否是由于不同类型的行尾(\r\n vs \n)。我也在搜索 not 匹配模式的文件。 :)
        • 是的,如果您的行尾是\r\n,那么只需在脚本中将\n 更改为\r\n,但这不可能,因为您接受的解决方案假定\n 行尾。如果要搜索不以字符串开头的文件,只需将==更改为!=即可。
        猜你喜欢
        • 1970-01-01
        • 2014-11-30
        • 1970-01-01
        • 2015-07-12
        • 2016-08-26
        • 2011-05-01
        • 2012-11-06
        • 1970-01-01
        • 2016-04-16
        相关资源
        最近更新 更多