ChatGPT解决这个技术问题 Extra ChatGPT

如何对目录中的所有文件执行grep操作?

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

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

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


u
umi

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"
P
Philippe Fanaro

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

grep -rni "string" *

在哪里

= 递归,即在当前目录中搜索子目录

= 将行号打印到标准输出

= 不区分大小写的搜索


R
Rob

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

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 似乎实际上并不想遍历子目录。
现代 find 上的 -exec 支持快捷方式,就像 xargs 一样,实际上会更快(因为您删去了 xargs)。使用 -exec ... {} + 而不是 -exec ... {} \;
N
Noam Manos

要搜索所有子目录,但仅限特定文件类型,请将 grep 与 --include 结合使用。

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

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

b
bryan

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

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"。)