使用正则表达式进行搜索或使用 grep 进行查找,哪种更好?

使用正则表达式进行搜索或使用 grep 进行查找,哪种更好?

这两种在所有子目录中递归搜索文件的方法,哪种更快/更好?

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或执行任何管道;但我怀疑你能注意到。

相关内容