`{}`是什么意思作为egrep输出中的文件名?

时间:2015-10-13 19:20:38

标签: grep echo

我在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。这是什么意思?

谢谢。

3 个答案:

答案 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可能应该放在文件的顶部