【问题标题】:How to perform grep operation on all files in a directory?如何对目录中的所有文件执行grep操作?
【发布时间】:2013-02-23 13:57:18
【问题描述】:

使用 xenserver,我想对目录中的每个文件执行命令,从命令的输出中提取一些内容并将其附加到文件中。

我很清楚我想使用的命令以及如何根据需要 grep 字符串。

但我不清楚的是如何让它对每个文件执行此命令,然后转到下一个文件,直到找不到更多文件。

【问题讨论】:

    标签: linux shell grep


    【解决方案1】:

    在 Linux 中,我通常使用此命令递归地 grep 获取目录中的特定文本:

    grep -rni "string" *
    

    在哪里

    • r = 递归,即在当前目录中搜索子目录
    • n = 将行号打印到stdout
    • i = 不区分大小写的搜索

    【讨论】:

      【解决方案2】:

      要在所有子目录中搜索,但只能在特定文件类型中搜索,请使用 grep 和 --include

      例如,在当前目录中递归搜索 *.yml 和 *.yaml 中的文本:

      grep "text to search" -r . --include=*.{yml,yaml}
      

      【讨论】:

        【解决方案3】:

        如果你想执行多个命令,你可以使用:

        for I in `ls *.sql`
        do
            grep "foo" $I >> foo.log
            grep "bar" $I >> bar.log
        done
        

        【讨论】:

        • 一般来说,可能在您发布的代码上尝试shellcheck.netDon't use ls to expand a wildcard(shell 已经为你做了!)和quote your shell variables
        • 您可能希望使用 Awk 来代替,尤其是在输入文件很大的情况下。 awk '/foo/ { print >"foo.log" } /bar/ { print >"bar.log" }' "$I" 在输入文件中一次搜索两种模式。 (如果您想搜索多个模式,但不需要多个输出文件,请尝试grep -E 'foo|bar' "$I"。)
        【解决方案4】:

        使用查找。说真的,这是最好的方法,因为这样您就可以真正看到它正在操作的文件:

        find . -name "*.sql" -exec grep -H "slow" {} \;
        

        注意,-H 是特定于 mac 的,它会在结果中显示文件名。

        【讨论】:

        • 如果您决定使用 find,通过xargs 管道输出而不是使用-exec,这将快得多,因为-exec 为每个 grep,并且大量文件的开销变得很大。关于文件名中空格的标准警告适用于xargs
        • 这会是什么样子?我总是忘记xargs 语法。
        • @BrianPeterson 会是这样的:find . -iname "*.sql" -print0 | xargs -0 grep "slow"
        • grep -r 提供了几乎相同的功能。 OP 似乎实际上并不想遍历子目录。
        • -exec 在现代find 上支持快捷方式,就像xargs 一样,实际上会更快(因为你删掉了xargs)。使用-exec ... {} + 而不是-exec ... {} \;
        【解决方案5】:

        grep $PATTERN * 就足够了。默认情况下,grep 会跳过所有子目录。但是,如果您想通过它们 grep,grep -r $PATTERN * 就是这种情况。

        【讨论】:

        • "grep -r $PATTERN 。"足够了。对于递归 grep,您不需要指定所有文件
        • 如何包含多个扩展?例如。 “*.cpp”、“*.h”?
        • @Tomáš Zato,只需提供所有文件模式而不是 *:grep $PATTERN *.cpp *.h。如果您需要更具体的规则来确定应该对哪些文件进行 grep,请使用 find 命令(查看 Rob 的答案)。
        • @Chris 您可能在当前目录中没有*.scss 文件,但在子目录更深处的某个位置,因此 grep 不会查看您想要的所有文件。您应该使用 --include 选项告诉 grep 递归查找与特定模式匹配的文件:grep -r x --include '*.scss' . (请注意引号,它们会阻止 shell 扩展模式)。或者只使用find(参见 Rob 的回答)。
        • 您需要grep -s,这样您就不会收到grep 跳过的每个子目录的警告。您可能应该在此处双引号 "$PATTERN"
        猜你喜欢
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-05
        • 1970-01-01
        • 2022-01-04
        • 1970-01-01
        • 2016-02-08
        • 2012-03-29
        相关资源
        最近更新 更多