【发布时间】:2013-02-23 13:57:18
【问题描述】:
使用 xenserver,我想对目录中的每个文件执行命令,从命令的输出中提取一些内容并将其附加到文件中。
我很清楚我想使用的命令以及如何根据需要 grep 字符串。
但我不清楚的是如何让它对每个文件执行此命令,然后转到下一个文件,直到找不到更多文件。
【问题讨论】:
使用 xenserver,我想对目录中的每个文件执行命令,从命令的输出中提取一些内容并将其附加到文件中。
我很清楚我想使用的命令以及如何根据需要 grep 字符串。
但我不清楚的是如何让它对每个文件执行此命令,然后转到下一个文件,直到找不到更多文件。
【问题讨论】:
在 Linux 中,我通常使用此命令递归地 grep 获取目录中的特定文本:
grep -rni "string" *
在哪里
r = 递归,即在当前目录中搜索子目录n = 将行号打印到stdout
i = 不区分大小写的搜索【讨论】:
要在所有子目录中搜索,但只能在特定文件类型中搜索,请使用 grep 和 --include。
例如,在当前目录中递归搜索 *.yml 和 *.yaml 中的文本:
grep "text to search" -r . --include=*.{yml,yaml}
【讨论】:
如果你想执行多个命令,你可以使用:
for I in `ls *.sql`
do
grep "foo" $I >> foo.log
grep "bar" $I >> bar.log
done
【讨论】:
ls to expand a wildcard(shell 已经为你做了!)和quote your shell variables。
awk '/foo/ { print >"foo.log" } /bar/ { print >"bar.log" }' "$I" 在输入文件中一次搜索两种模式。 (如果您想搜索多个模式,但不需要多个输出文件,请尝试grep -E 'foo|bar' "$I"。)
使用查找。说真的,这是最好的方法,因为这样您就可以真正看到它正在操作的文件:
find . -name "*.sql" -exec grep -H "slow" {} \;
注意,-H 是特定于 mac 的,它会在结果中显示文件名。
【讨论】:
xargs 管道输出而不是使用-exec,这将快得多,因为-exec 为每个 grep,并且大量文件的开销变得很大。关于文件名中空格的标准警告适用于xargs。
xargs 语法。
find . -iname "*.sql" -print0 | xargs -0 grep "slow"
grep -r 提供了几乎相同的功能。 OP 似乎实际上并不想遍历子目录。
-exec 在现代find 上支持快捷方式,就像xargs 一样,实际上会更快(因为你删掉了xargs)。使用-exec ... {} + 而不是-exec ... {} \;
grep $PATTERN * 就足够了。默认情况下,grep 会跳过所有子目录。但是,如果您想通过它们 grep,grep -r $PATTERN * 就是这种情况。
【讨论】:
grep $PATTERN *.cpp *.h。如果您需要更具体的规则来确定应该对哪些文件进行 grep,请使用 find 命令(查看 Rob 的答案)。
*.scss 文件,但在子目录更深处的某个位置,因此 grep 不会查看您想要的所有文件。您应该使用 --include 选项告诉 grep 递归查找与特定模式匹配的文件:grep -r x --include '*.scss' . (请注意引号,它们会阻止 shell 扩展模式)。或者只使用find(参见 Rob 的回答)。
grep -s,这样您就不会收到grep 跳过的每个子目录的警告。您可能应该在此处双引号 "$PATTERN"。