我如何递归grep?

wpi*_*iri 1619 unix linux grep

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

find . | xargs grep "texthere" *
Run Code Online (Sandbox Code Playgroud)

Vin*_*vic 2430

grep -r "texthere" .
Run Code Online (Sandbox Code Playgroud)

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

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

  • 使用grep -R跟随符号链接. (102认同)
  • 很高兴知道"-i"会使它不区分大小写," - n"也包含每个匹配结果的行号. (51认同)
  • 注意:"grep -r"仅适用于较新的greps.例如,它不适用于`AIX 5.3`附带的grep. (36认同)
  • 另外要知道的是,如果您只是寻找固定字符串而不是正则表达式,请使用-F选项.它会通过不调用正则表达式解析器来节省大量时间.如果你正在搜索大量的文件非常方便. (22认同)
  • 别名rgrep ='grep -r' (6认同)
  • 在Cygwin上,为了搜索隐藏文件(以点开头)并在其中,你需要使用`find.-type f | xargs grep -l"搜索字符串"`.Cygwin上单独使用`grep -r`不会搜索隐藏文件. (5认同)
  • 这不应该是公认的答案,因为问题带有“unix”标签,并且它不适用于许多 Unix,包括 HP-UX 和 AIX(但它应该适用于 Linux)。相反,这些操作系统需要使用 find 命令,如 https://unix.stackexchange.com/a/24917/141272 中所述 (2认同)
  • 如果省略了 `.` 会发生什么? (2认同)
  • 当递归执行此操作时,我经常想知道内容所在的文件。您可以通过添加选项“--with-filename”来获得此信息。 (2认同)

chr*_*ant 655

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

grep -r --include "*.txt" texthere .
Run Code Online (Sandbox Code Playgroud)

您还可以提及要排除的文件--exclude.

如果你经常搜索代码,Ag(The Silver Searcher)是一个比grep更快的替代品,它是为搜索代码而定制的.例如,它默认是递归的,并自动忽略列出的文件和目录.gitignore,因此您不必继续将相同的繁琐排除选项传递给grep或find.

  • @DanDascalescu我赞成了'grep`,而不是Ag,只是让你知道:) (4认同)
  • 适用于Linux和Cygwin附带的grep,但不适用于AIX附带的grep. (3认同)
  • 我们是否可以选择在递归搜索时排除目录? (2认同)

Kur*_*urt 124

也:

find ./ -type f -print0 | xargs -0 grep "foo"
Run Code Online (Sandbox Code Playgroud)

但是grep -r更好的答案.

  • +1这适用于HP-UX,其中"grep -r"没有.谢谢. (45认同)
  • 或者如果你不想担心文件名中的空格`find.-type f -exec grep"foo"'{}'\;`在支持的地方运行良好. (13认同)
  • +1这适用于AIX,其中"grep -r"没有. (7认同)
  • 如果您要通过xargs管道查找grep,如果您只搜索固定字符串(即,不是正则表达式),您可能会受益于调用grep -F选项,因此grep将不会加载正则表达式引擎对于每次调用.如果有很多文件会更快. (4认同)
  • 找 .-type f -exec grep -Hu"foo"{} \; 是我用它,因为它给出了文件名. (2认同)
  • `find ./ -type f -print0 | xargs -0 grep "foo"` (2认同)

Von*_*onC 111

我现在总是使用(甚至在Windows上使用GoW - Gnu在Windows上):

grep --include="*.xxx" -nRHI "my Text to grep" *
Run Code Online (Sandbox Code Playgroud)

这包括以下选项:

--include=PATTERN
Run Code Online (Sandbox Code Playgroud)

递归仅搜索文件匹配的目录PATTERN.

-n, --line-number
Run Code Online (Sandbox Code Playgroud)

使用输入文件中的行号为每行输出添加前缀.

(注意:phuclv 在评论中 添加-n了很多性能,因此您可能希望跳过该选项)

-R, -r, --recursive
Run Code Online (Sandbox Code Playgroud)

递归地读取每个目录下的所有文件; 这相当于-d recurse选项.

-H, --with-filename
Run Code Online (Sandbox Code Playgroud)

打印每个匹配的文件名.

-I     
Run Code Online (Sandbox Code Playgroud)

处理二进制文件,就好像它不包含匹配数据一样;
这相当于--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;
...
Run Code Online (Sandbox Code Playgroud)

  • 这里最后一个字符*是什么意思? (3认同)
  • @lorniper它使shell选择当前目录中的所有文件和文件夹,反过来grep应用于这些文件和(递归地因为`-R`选项)到文件夹. (2认同)
  • @lorniper Noy究竟:`*`或`.`是一个glob模式(由shell解释):http://unix.stackexchange.com/a/64695/7490.'.``'也会选择点文件或点文件夹(如`.git /`) (2认同)

roo*_*ook 22

在POSIX系统中,您没有找到-r参数,grep并且您grep -rn "stuff" .将无法运行,但如果使用find命令,它将:

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

同意SolarisHP-UX.

  • 是什么意思 {} \; - 分别打印? (2认同)
  • 在`-exec`选项中 - 符号`{}`是对`find`工具当前找到的文件名的引用(即用我们找到的文件名做某事),`-exec`选项也应该以`` ;`符号(用于标记exec命令的结尾),但因为这一切都在shell中运行,符号应该被转义..最后`-print`选项让`find`工具在屏幕上打印出找到的文件名. (2认同)

ken*_*orb 19

通配符 **

使用grep -r作品,但它可能过度,特别是在大文件夹中.

有关更实际的用法,以下是使用globbing语法(**)的语法:

grep "texthere" **/*.txt
Run Code Online (Sandbox Code Playgroud)

仅使用模式选择模式对特定文件进行grepping.它适用于支持的shell,如Bash +4zsh.

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

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

git grep

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

git grep "pattern"
Run Code Online (Sandbox Code Playgroud)

哪个更快.

ripgrep

对于较大的项目,最快的ripgrepgrepping 工具是默认情况下递归greps文件:

rg "pattern" .
Run Code Online (Sandbox Code Playgroud)

它建立在Rust的正则表达式引擎之上,它使用有限自动机,SIMD和积极的文字优化来快速搜索.在这里查看详细分析.

  • 感谢git grep建议 - 它非常有用,我不知道它! (3认同)
  • 感谢ripgrep的建议。它的速度更快。 (2认同)

gee*_*eek 15

另一种在 Linux 系统上的所有文件中递归地 grep 字符串的语法

grep -irn "string"
Run Code Online (Sandbox Code Playgroud)

命令的细分

 -r, --recursive
Run Code Online (Sandbox Code Playgroud)

表示recursive在给定目录和子目录中查找指定字符串的搜索,在文件、二进制文件等中查找特定字符串

-i, --ignore-case
Run Code Online (Sandbox Code Playgroud)

忽略大小写,可用于添加大小写颠倒的字符串

-n, --line-number
Run Code Online (Sandbox Code Playgroud)

打印找到的文件中指定字符串的行号

注意:这会将大量结果打印到控制台,因此您可能需要通过管道过滤输出并删除不太有趣的信息。它还搜索二进制程序,因此您可能想要过滤一些结果


chi*_*him 11

只是文件名也很有用

grep -r -l "foo" .
Run Code Online (Sandbox Code Playgroud)


Gir*_*ore 11

要查找filespath递归方式包含string以下命令的特定用途的名称UNIX:

find . | xargs grep "searched-string"
Run Code Online (Sandbox Code Playgroud)

用于Linux:

grep -r "searched-string" .
Run Code Online (Sandbox Code Playgroud)

UNIX服务器上找到一个文件

find . -type f -name file_name
Run Code Online (Sandbox Code Playgroud)

在LINUX服务器上找到一个文件

find . -name file_name
Run Code Online (Sandbox Code Playgroud)


Sar*_*lly 9

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

grep -r "thingToBeFound" directory
Run Code Online (Sandbox Code Playgroud)

如果你想跟随符号链接和实际目录(注意无限递归),

grep -R "thing to be found" directory
Run Code Online (Sandbox Code Playgroud)

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

-H: outputs the filename with the line

-n: outputs the line number in the file
Run Code Online (Sandbox Code Playgroud)

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

grep -rnH "Darth Vader" .
Run Code Online (Sandbox Code Playgroud)

如果你想在目录中找到所有提到的单词cat

/home/adam/Desktop/TomAndJerry 
Run Code Online (Sandbox Code Playgroud)

而你目前在目录中

/home/adam/Desktop/WorldDominationPlot
Run Code Online (Sandbox Code Playgroud)

并且您想要捕获文件名但不是字符串"cats"的任何实例的行号,并且您希望递归遵循符号链接,如果找到它们,您可以运行以下任一项

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

grep -RH "cats" /home/adam/Desktop/TomAndJerry   #absolute directory
Run Code Online (Sandbox Code Playgroud)

资源:

运行"grep --help"

关于符号链接的简短介绍,对于任何阅读这个答案并且被我对它们的引用感到困惑的人:https: //www.nixtutor.com/freebsd/understanding-symbolic-links/


dra*_*nxo 8

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
Run Code Online (Sandbox Code Playgroud)


sum*_*mar 6

这应该工作:

grep -R "texthere" *
Run Code Online (Sandbox Code Playgroud)


fed*_*qui 6

如果您要从目录结构中查找所有文件中的特定内容,您可以使用,find因为您更清楚自己在做什么:

find -type f -exec grep -l "texthere" {} +
Run Code Online (Sandbox Code Playgroud)

请注意-l(L的小写)显示包含文本的文件的名称.如果您想要打印匹配本身,请将其删除.或者用于-H将文件与匹配一起获取.总之,其他替代方案是:

find -type f -exec grep -Hn "texthere" {} +
Run Code Online (Sandbox Code Playgroud)

在哪里-n打印行号.

  • 向上投票是唯一的`find`解决方案,既避免了不必要的使用`xargs`又使用`+`而不是'\;`和`-exec`,从而避免了大量不必要的进程启动.:-) (2认同)

Geo*_*ale 6

grep -r "texthere" . (通知期见文末)

(^信用:/sf/answers/139154991/


澄清:

grep -r "texthere" /(递归地 grep所有目录和子目录)

grep -r "texthere" .(递归地grep这些目录和子目录)

grep 递归

grep [options] PATTERN [FILE...]

[选项]

-R, -r, --recursive

递归读取每个目录下的所有文件。

这相当于-d recurseor--directories=recurse选项。

http://linuxcommand.org/man_pages/grep1.html

grep 帮助

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive
Run Code Online (Sandbox Code Playgroud)

备择方案

ackhttp://beyondgrep.com/

aghttp://github.com/ggreer/the_silver_searcher


ark*_*kod 6

这是我当前机器上的情况(Windows 7上的git bash):

find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Run Code Online (Sandbox Code Playgroud)

对于带空格的路径,我总是忘记-print0和-0.

编辑:我现在的首选工具是ripgrep:https://github.com/BurntSushi/ripgrep/releases.它真的很快并且具有更好的默认值(默认情况下是递归的).与我原来的答案相同,但使用ripgrep:rg -g "*.cs" "content pattern"


Zst*_*ack 6

把我的两分钱扔在这里。正如其他人已经提到的那样,grep -r并不适用于每个平台。这可能听起来很傻,但我总是使用 git。

git grep "texthere"
Run Code Online (Sandbox Code Playgroud)

即使目录没有暂存,我也只是暂存它并使用 git grep。


Gir*_*ore 5

String以下是递归搜索Unix环境的命令Linux

命令UNIX是:

find . -name "string to be searched" -exec grep "text" "{}" \;
Run Code Online (Sandbox Code Playgroud)

命令Linux是:

grep -r "string to be searched" .
Run Code Online (Sandbox Code Playgroud)


hug*_*own 5

2018 年,您想要使用ripgrep或 ,the-silver-searcher因为它们比其他替代方案快得多。

这是一个包含 336 个一级子目录的目录:

% find . -maxdepth 1 -type d | wc -l
     336

% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py'  1.24s user 2.23s system 283% cpu 1.222 total

% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$'  2.71s user 1.55s system 116% cpu 3.651 total

% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py'  1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs  6.65s user 0.49s system 32% cpu 22.164 total
Run Code Online (Sandbox Code Playgroud)

在 OSX 上,这会安装ripgrepbrew install ripgrep。这将安装silver-searcherbrew install the_silver_searcher.

  • 如果您需要经常这样做,速度就很重要,但我们大多数人发现自己一年最多只这样做几次。安装最新的第三方 juju 工具 du jour 有点过分了,无论如何,了解自 1978 年以来没有太大变化的解决方案是件好事。 (3认同)
  • 你忘记了“查找”。-type f -exec grep 'regex' {} +` 如果您定期使用这些工具,这确实很容易记住。但如果您需要经常查找内容,您可能应该在源代码树上运行“ctags”或“etags”。 (2认同)