如何使用 -EXEC grep FIND 的结果并仍然输出到文件?

如何使用 -EXEC grep FIND 的结果并仍然输出到文件?

最好用例子来解释。

我可以:

find . -name "*.py" -type f > output.txt

但是如何将输出存储到同一文件中:

find . -name "*.py" -type f -exec grep "something" {} \

我不能只是做

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt

答案1

如果我理解正确的话,这就是你想要做的:

find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt

查找所有具有扩展名的文件.pygrep仅包含包含行something并将行保存在 中的行output.txt。如果output.txt文件存在,则将其截断,否则将创建该文件。

使用-exec

find . -name '*.py' -exec grep 'something' {} \; > output.txt

我在这里合并 Chris Downs 的评论:上述命令将导致grep执行多次,以find查找通过给定测试的路径名(仅上面的单个-name测试)。但是,如果将 替换\;+,grep则会使用多个路径名find(最多一定限制)进行调用。

查看问题在 find 中使用分号 (;) 与加号 (+) 与 exec 的比较有关该主题的更多信息。

答案2

如果您想保存 中所有文件的所有匹配行output.txt,则最后一个命令确实有效,只是您缺少;命令末尾所需的内容。

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt

如果您希望每次运行都grep将输出生成到不同的文件,请运行 shell 来计算输出文件名并执行重定向。

find . -name "*.py" -type f -exec sh -c 'grep "something" <"$0" >"$0.txt"' {} \;

答案3

根据记录,GNUgrep--include--exclude参数,您可以使用它们来过滤它搜索的文件:

grep -r --include="*.py" "something" > output.txt

答案4

你问:

但是如何将输出存储到同一文件中:

find . -name "*.py" -type f -exec grep "something" {} \

你误会了。您无法将其传递给任何内容的原因是它不是完整的命令。结束语\告诉您的 shell 继续读取下一行的命令,但这不是您打算在此处执行的操作。当你尝试时:

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt

转义\一个空白字符,因此,该字符将作为额外参数传递给find,并且find会抱怨传递给其选项的命令-exec没有被终止。

必须通过添加+or;标记来终止该命令,并且该;标记对于 shell 来说是特殊的,因此必须对其进行转义或引用。此外,{}在大多数 shell 中也很特殊,因此也必须对它们进行转义或引用:

find . -name "*.py" -type f -exec grep "something" \{} \;

或者

find . -name "*.py" -type f -exec grep "something" '{}' ';'

这些是有效的命令,因此您可以很好地重定向和管道它们的输出:

find . -name "*.py" -type f -exec grep "something" \{} \; > output.txt
find . -name "*.py" -type f -exec grep "something" '{}' + | fgrep -v notthesefiles: > output.txt

顺便说一句,如果我不希望 shell 解释其中的任何字符,我更喜欢使用单引号参数,即使(正如 @Kusalananda 指出的那样),在这种情况下这是不必要的:

find . -name '*.py' -type f -exec grep 'something' \{} \; > output.txt

;对于和之间的区别+,请尝试man find

相关内容