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


64

更好地解释例子。

我可以:

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

Answers:


105

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

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

Find所有带扩展名的文件pygrep只有包含something和保存行的行output.txt。如果文件包含任何内容,它将被替换。

编辑:使用-exec:

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

我将Chris Downs的评论纳入此处。上面的命令将导致grep执行与find发现事件一样多的次数。但是,如果将替换;+grep则会从find串联的输出中调用(达到一定的限制)。有关查找更多关于该主题的信息,请参见在exec中使用分号(;)与加号(+)的问题。


16
使用+代替\;,将显着缩短执行时间(因为它将在执行之前先处理参数直到ARG_MAX)。
克里斯·

现在,我了解了xargs的强大功能!谢谢!
domih's

4
grep -H如果要在输出中包括文件名,请使用。
Steinar '18

18

如果您要在中的所有文件中保存所有匹配的行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"' {} \;

最后一个真的很不错:D
bakytn11

要扩展@gilles答案以使其更具信息性,特别是如果您正在处理的文件列表很大,则可以使用此命令报告每个文件的文件名(相对路径)以及grep的结果: find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt 而且,如果您想查看grep标记行的行号,可以使用grep -n "something"
JJMpls 2014年

9

作为记录,grep具有--include--exclude参数可用于过滤其搜索的文件:

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

2
至少GNU grep会这样做。
phk

2

用途tee

find . -name '*.py' | tee output.txt | xargs grep 'something'

需要说明的是,如果你有特殊字符(含空格)的任何文件xargs,并grep不会很好地工作(a file.txt将被解释为两个文件,afile.txt)。替代方法是使用-x-print0,但其中任何一个都会污染您的output.txt。在-x将使用\逃脱某些特殊字符,这将是output.txt。在-print0将使用一个空字节作为一个字段分隔符(这也需要xargs -0),并output.txt看起来像文本的一个长的连续线。

您如何处理(或不处理)这取决于您。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.