我在ubuntu debian 12.04上运行了一个find命令,为我的所有python文件添加了一些内容:
find . iname "*.py" -exec echo "import os" >> {} \;
该命令运行没有错误,我想验证结果,所以我egrep所有文件:
egrep -in "import os" *
我得到的结果如下:
{}:35:import os
{}:36:import os
{}:37:import os
{}:38:import os
{}:39:import os
......由于某种原因,数字会一直持续到51。这是什么意思?
谢谢。
答案 0 :(得分:2)
你的第一个命令:
find . iname "*.py" -exec echo "import os" >> {} \;
正在查找以.py结尾的文件,并且每个文件都将字符串“import os”放在名为{}
的文件中。据推测,有51场比赛。
所以egrep,当你运行它时,*
匹配所有文件,包括名为{}
的文件。使用{}:35:import os
,它告诉你“在文件{}中,在第35行,有你正在寻找的字符串”
答案 1 :(得分:1)
此命令:
find . iname "*.py" -exec echo "import os" >> {} \;
...创建一个名为{}
的文件(在bash中,以及其他在头和尾以外的位置都有重定向的shell - 这是POSIX sh标准不需要的扩展名)。 不修改find
找到的文件。 (这是因为>>
充当了开始find
的shell的命令;它不会修改-exec
的行为 - 即使它已经改变了-exec
直接使用execve()
来调用给定的命令;它不会通过shell启动该命令,因此它不支持shell构造(如重定向),因此您将传递文字>>
作为echo
在没有实现此扩展的shell上的参数,仍然没有对找到的单个文件执行重定向。)
现在,如果您 希望修改find
找到的文件,您可以这样做:
find . -iname '*.py' -exec sh -c 'for f; do echo "import os" >>"$f"; done' {} +
值得注意的差异:
exec sh
开头的shell中调用重定向;因此,在解决了各个文件名后,会有一个shell来表示它。-exec ... {} +
,它比-exec ... {} ;
更有效率(前者运行尽可能少的子命令;后者每找到一个文件运行一个)。答案 2 :(得分:1)
{}
是一个占位符,由find
替换,其文件名与给定条件匹配,在这种情况下,{}
将替换为与模式"*.py"
匹配的文件名
但是你的find
命令实际上并没有这样做,因为>> {}
实际上不是-exec
块的一部分,而是由shell解释为重定向整个find
命令,因此{}
永远不会被find
替换为正确的文件名,而是重定向到名为{}
的文件中。为了使事情更清楚,您实际执行的命令是:
find . iname "*.py" -exec echo "import os" \; >> {}
每个*.py
文件的含义你添加一行包含" import os"到名为{}
的文件中。 grep
的输出只有filename:linenumber:matched_line
,因此您可以在其中获得{}
,因为这是文件名。
如果您想知道\;
如何存活以及为什么没有得到:
find: missing argument to `-exec'
shell实际上并不关心命令行中重定向发生的位置:
echo 1 2 3 4 5 6 7 > foo
与:
相同echo 1 2 > foo 3 4 5 6 7
每次都给你这个:
$ cat foo
1 2 3 4 5 6 7
另外值得一提的是>>
是一个追加运算符,所以即使你修改了命令,你也要添加到Python文件的末尾,而import os
可能应该放在文件的顶部