我正在使用 find 命令来查看它的行为,但我有点迷失。
第一位很好:
find . -maxdepth 1 -exec grep -l abc {} \;
grep: .: Is a directory
./file2.pdf
./file1
然后我尝试通过链接另一个 egrep 命令来排除 .pdf 文件,但失败了。
find . -maxdepth 1 -exec grep -l abc {} \; -exec egrep -vl '*.pdf' {} \;
grep: .: Is a directory
./file2.pdf
./file2.pdf
./file1
./file1
为什么它不排除 .pdf 文件并且还打印两次结果?
答案1
egrep -vl '*.pdf' some_file
检查文件内容,不是名字。
排除名称的正确方法find
是否定(!
)适当的-name
(或-iname
如果可用)表达式。例如:
find . -maxdepth 1 ! -name '*.pdf' -exec grep -l abc {} \;
每个结果都打印两次,因为在第一次grep
打印并返回成功之后,第二次(egrep
)显然没有*.pdf
在相应的文件内容中找到(解释为扩展正则表达式),因此(注意-v
)打印了相同的名称。
注意-exec
,这也是一个测试。在你的情况下,如果第一个-exec
报告失败,则第二个-exec
将不会被触发。-exec
如果第一个报告grep
失败,它将报告失败。grep
如果在文件中找不到模式,它将报告失败。这意味着第一个未打印的任何文件都grep
无法由第二个打印(egrep
),因为第二个甚至不会为该文件运行。
排除.pdf
文件的另一种方法是过滤输出你的第一个find
(在你的情况下实际上是grep
s 的输出;你find
本身没有打印任何内容)。像这样:
find . -maxdepth 1 -exec grep -l abc {} \; | grep -iv '\.pdf$'
但是如果由 返回的任何路径find
是多行的(即如果它包含换行符;Linux 中的文件名可以),则添加的grep
将无论如何分别感知每一行,就好像这些行引用了多个文件一样;并且您将得到意想不到的结果。因此在find
( -name …
) 内进行测试更好。