![在文件 find 和 grep 中搜索字符串的有效方法](https://linux22.com/image/1367568/%E5%9C%A8%E6%96%87%E4%BB%B6%20find%20%E5%92%8C%20grep%20%E4%B8%AD%E6%90%9C%E7%B4%A2%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%9C%89%E6%95%88%E6%96%B9%E6%B3%95.png)
我正在文件管理器(在旧的 HP-UX 工作站上)上搜索包含特定字符串的所有文件。
我不知道文件在文件系统中的位置(有很多目录,其中包含大量脚本、纯文本和二进制文件)。
我明确指出该系统上不存在 grep -R 选项;因此我使用 find 和 grep 来检索哪些文件包含我的字符串:
find . -type f -exec grep -i "mystring" {} \;
我对这个命令不满意:它太慢了,而且它不会打印 grep 与我的字符串匹配的文件的名称和路径。此外,如果出现错误,它将在我的控制台输出中回显。
所以我认为我可以做得更好:
find . -type f -exec grep -l -i "mystring" {} 2>/dev/null \;
但是它非常慢。
您是否有比该命令更有效的替代方法?
感谢您。
答案1
我能想到的最快的方法是使用来xargs
分担负载:
find . -type f -print0 | xargs -0 grep -Fil "mypattern"
在包含 3631 个文件的目录上运行一些基准测试:
$ time find . -type f -exec grep -l -i "mystring" {} 2>/dev/null \;
real 0m15.012s
user 0m4.876s
sys 0m1.876s
$ time find . -type f -exec grep -Fli "mystring" {} 2>/dev/null \;
real 0m13.982s
user 0m4.328s
sys 0m1.592s
$ time find . -type f -print0 | xargs -0 grep -Fil "mystring" >/dev/null
real 0m3.565s
user 0m3.508s
sys 0m0.052s
您的其他选择是通过使用以下方法限制文件列表来简化操作find
:
-executable
Matches files which are executable and direc‐
tories which are searchable (in a file name
resolution sense).
-writable
Matches files which are writable.
-mtime n
File's data was last modified n*24 hours ago.
See the comments for -atime to understand how
rounding affects the interpretation of file
modification times.
-group gname
File belongs to group gname (numeric group ID
allowed).
-perm /mode
Any of the permission bits mode are set for
the file. Symbolic modes are accepted in this
form. You must specify `u', `g' or `o' if you
use a symbolic mode.
-size n[cwbkMG] <-- you can set a minimum or maximum size
File uses n units of space.
或者通过调整grep
:
您已经使用了grep
的-l
选项,它会导致打印文件名,更重要的是,在第一个匹配处停止:
-l, --files-with-matches
Suppress normal output; instead print the name of each input file from
which output would normally have been printed. The scanning will stop
on the first match. (-l is specified by POSIX.)
我能想到的唯一其他加快速度的方法是通过使用该-F
选项确保您的模式不会被解释为正则表达式(如@suspectus 所建议的)。
答案2
使用grep -F
,它告诉grep
将模式解释为字符串而不是正则表达式(我假设您不需要)。它可以比grep
- 快得多,具体取决于正在解析的文件的大小。
在 Ubuntu 和 RHEL Linux 上,-H 选项将显示匹配文件的文件路径。
find . -type f -exec grep -FHi "mystring" {} +