如何递归 grep?

如何递归grep所有目录和子目录?

find . | xargs grep "texthere" *

答案

grep -r "texthere" .

第一个参数表示要搜索的正则表达式,而第二个参数表示应搜索的目录。在这种情况下, .表示当前目录。

注意:这适用于 GNU grep,在某些平台(如 Solaris)上,必须专门使用 GNU grep 而不是传统实现。对于 Solaris,这是ggrep命令。

如果知道所需的文件扩展名或模式,则另一种方法是使用--include选项:

grep -r --include "*.txt" texthere .

您还可以使用--exclude提及要排除的文件。

如果您经常搜索代码, Ag(银搜索器)是 grep 的一种更快的选择,它是为搜索代码而定制的。例如,默认情况下它是递归的,并且会自动忽略.gitignore列出的文件和目录,因此您不必.gitignore将相同的繁琐排除选项传递给 grep 或 find。

也:

find ./ -type f -print0 | xargs -0 grep "foo"

但是grep -r是一个更好的答案。

我现在总是使用(即使在带有GoW 的 Windows 上-Windows 上的 Gnu ):

grep --include="*.xxx" -nRHI "my Text to grep" *

其中包括以下选项:

--include=PATTERN

仅在目录中搜索匹配PATTERN文件时递归。

-n, --line-number

在输出的每一行之前,在其输入文件中添加行号。

(注意: phuclv 在注释中添加 -n从而 大大 降低了性能 ,因此您可能要跳过该选项)

-R, -r, --recursive

递归读取每个目录下的所有文件;这等效于-d recurse选项。

-H, --with-filename

打印每个匹配项的文件名。

-I

处理二进制文件,就好像它不包含匹配的数据一样;
这等效于--binary-files=without-match选项。

如果我想要不区分大小写的结果,可以添加 ' i '(- -nRHIi )。

我可以得到:

/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43:            'git.hidden'      => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21:            $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32:        $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20:    protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170:     * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176:        return $this->hidden;
...

在 POSIX 系统中,找不到grep -r参数和grep -rn "stuff" .将不会运行,但是如果您使用find命令,它将:

find . -type f -exec grep -n "stuff" {} \; -print

SolarisHP-UX同意。

**

使用grep -r可以工作,但是可能会过大,尤其是在大文件夹中。

为了更实际的使用,以下是使用通配语法** )的语法

grep "texthere" **/*.txt

仅抓取具有选定图案的图案的特定文件。它适用于受支持的 shell,例如Bash +4zsh

要激活此功能,请运行: shopt -s globstar

另请参阅: 如何在 Linux 上查找所有包含特定文本的文件?

git grep

对于受 Git 版本控制的项目,请使用:

git grep "pattern"

这要快得多。

ripgrep

对于大型项目,最快的ripgrep工具是ripgrep ,默认情况下会递归地处理文件:

rg "pattern" .

它建立在Rust 的正则表达式引擎之上,该引擎使用有限自动机,SIMD 和积极的文字优化来使搜索变得非常快。在此处检查详细分析

只是文件名也可能有用

grep -r -l "foo" .

要查找path递归包含特定stringfiles名,请对UNIX使用以下命令:

find . | xargs grep "searched-string"

对于Linux

grep -r "searched-string" .

UNIX服务器上查找文件

find . -type f -name file_name

在 LINUX 服务器上查找文件

find . -name file_name

如果您只想遵循实际目录,而不是符号链接,

grep -r "thingToBeFound" directory

如果您想跟踪符号链接以及实际目录(请注意无限递归),

grep -R "thing to be found" directory

由于您尝试递归 grep,因此以下选项对您可能也很有用:

-H: outputs the filename with the line

-n: outputs the line number in the file

因此,如果要在当前目录或任何子目录中查找包含 Darth Vader 的所有文件,并捕获文件名和行号,但是不希望递归遵循符号链接,则命令为

grep -rnH "Darth Vader" .

如果您想在目录中找到所有提及猫这个词

/home/adam/Desktop/TomAndJerry

并且您当前在目录中

/home/adam/Desktop/WorldDominationPlot

并且要捕获文件名而不是字符串 “cats” 的任何实例的行号,并且希望递归遵循符号链接(如果找到它们),则可以运行以下任一命令

grep -RH "cats" ../TomAndJerry                   #relative directory

grep -RH "cats" /home/adam/Desktop/TomAndJerry   #absolute directory

资源:

运行 “grep --help”

对符号链接的简短介绍,适用于阅读此答案并因我对其引用感到困惑的任何人: https : //www.nixtutor.com/freebsd/understanding-symbolic-links/

ag 是我现在最喜欢的方法github.com/ggreer/the_silver_searcher 。它与 ack 基本相同,但还有更多优化。

这是一个简短的基准。我在每次测试前都要清除缓存( 参阅https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache

ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .

real    0m9.458s
user    0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .

real    0m6.296s
user    0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .

real    0m5.641s
user    0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache

real    0m0.154s
user    0m0.224s
sys 0m0.172s