这两种在所有子目录中递归搜索文件的方法,哪种更快/更好?
find . -regex ".*/.*abc.*"
或者
find . | grep ".*abc.*"
答案1
UNIX 文件名通常可以由八位字节(8 位字节)组成,但 0x00 (NULL) 和 0x2F (/) 除外。其他所有八位位组均有效。这包括诸如 0x0A(换行符)之类的好东西。
您的find
示例将正确处理带有奇怪字符(例如换行符)的文件名。
find | grep
当面对这样的事情时,你的例子会给出奇怪和不正确的结果(它会看到一名为“第 1 行\n第 2 行”的文件为二文件)。
您可以使用find -print0 | grep -z
(如果您使用的是 GNU 版本,例如在 Linux 上);这将保持正确性。它将使用更多的内存。请注意,您可以使用 选项告诉 find 使用扩展正则表达式(例如)-regextype
。
如果您想做一些非常复杂的匹配,您可能会喜欢这个find2perl
脚本,它将find
命令行转换为一个简短的 Perl 程序,然后您可以进行编辑以增加复杂性。
答案2
find . -regex ".*/.*abc.*"
更快,因为find . | grep ".*abc.*"
必须find
生成所有数据并将其传递给grep
.但差异可能很小。find . -regex ".*/.*abc.*"
也更可靠,因为即使在文件名带有空格的极少数情况下它也能工作。
请注意,这两个命令都会查找完整路径包含abc
.这不仅包括名称包含 的文件abc
,还包括名称包含 的目录中包含的文件abc
,递归地。要仅查找名称包含的文件abc
,请使用
find -name '*abc*'
在 ksh、bash 或 zsh 中,您可以echo **/*abc*
改为运行:**/
递归地查看所有子目录。在 ksh 中,您需要set -o globstar
先运行(将其放入您的~/.kshrc
)。在 bash 中,您需要shopt -s globstar
首先运行(将其放入您的~/.bashrc
)。
答案3
如果您使用模式匹配find
,您可以添加其他谓词或行为:
# look only for matching directories
find . -regex ".*/.*abc.*" -type d
# run a command on each match
find . -regex ".*/.*abc.*" -exec echo 'I found a file named {}' ';'
find
仅搜索可能会更快,因为您不需要生成进程grep
或执行任何管道;但我怀疑你能注意到。