我如何递归grep?

时间:2010-01-01 05:10:13

标签: linux unix grep

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

find . | xargs grep "texthere" *

26 个答案:

答案 0 :(得分:2316)

grep -r "texthere" .

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

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

答案 1 :(得分:626)

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

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

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

的Ag

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

答案 2 :(得分:121)

此外:

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

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

答案 3 :(得分:107)

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

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

包括以下选项:

--include=PATTERN
  

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

-n, --line-number
  

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

(注意:phuclv添加了in the comments -n decreases performance a lot so,因此您可能希望跳过该选项)

-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;
...

答案 4 :(得分:21)

在POSIX系统中,您找不到-r的{​​{1}}参数,而您的grep将无法运行,但如果您使用grep -rn "stuff" .命令,则会:< / p>

find

find . -type f -exec grep -n "stuff" {} \; -printSolaris同意。

答案 5 :(得分:17)

globbing **

使用grep -r有效,但可能过度,特别是在大型文件夹中。

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

grep "texthere" **/*.txt

仅覆盖具有模式选定模式的特定文件。它适用于受支持的shell,例如 Bash +4 zsh

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

另请参阅:How do I find all files containing specific text on Linux?

git grep

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

git grep "pattern"

更快。

ripgrep

对于较大的项目,最快的grepping工具是ripgrep,它默认递归地压缩文件:

rg "pattern" .

它建立在Rust's regex engine之上,它使用有限自动机,SIMD和积极的文字优化来快速搜索。查看detailed analysis here

答案 6 :(得分:11)

要查找files的名称,path递归地包含下面特定的string使用命令 UNIX

find . | xargs grep "searched-string"

代表Linux

grep -r "searched-string" .

UNIX服务器上找到一个文件

find . -type f -name file_name

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

find . -name file_name

答案 7 :(得分:10)

只是文件名也很有用

grep -r -l "foo" .

答案 8 :(得分:9)

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

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" .

如果你想在目录

中找到所有提到的单词cat
/home/adam/Desktop/TomAndJerry 

您目前位于目录

/home/adam/Desktop/WorldDominationPlot

并且你想要捕获文件名而不是字符串&#34; cats&#34;的任何实例的行号,并且你希望递归遵循符号链接,如果找到它们,你可以运行其中任何一个以下

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

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

来源:

跑步&#34; grep --help&#34;

对符号链接的简短介绍,对于阅读此答案的任何人而言,我对他们的提及感到困惑: https://www.nixtutor.com/freebsd/understanding-symbolic-links/

答案 9 :(得分:8)

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

这是一个简短的基准。我在每次测试之前清除缓存(cf 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

答案 10 :(得分:6)

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

find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"

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

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

答案 11 :(得分:6)

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

find -type f -exec grep -l "texthere" {} +

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

find -type f -exec grep -Hn "texthere" {} +

-n打印行号。

答案 12 :(得分:5)

这应该有效:

grep -R "texthere" *

答案 13 :(得分:4)

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

(^ credit:https://stackoverflow.com/a/1987928/1438029

<强>澄清:

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

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

grep recursive

  

grep [options] PATTERN [FILE...]

     

[选项]

     

-R, -r, --recursive

     

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

     

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

     

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

grep help

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

替代

ackhttp://beyondgrep.com/

aghttp://github.com/ggreer/the_silver_searcher

答案 14 :(得分:3)

以下是在StringUnix环境中以递归方式搜索Linux的命令。

UNIX命令的

是:

find . -name "string to be searched" -exec grep "text" "{}" \;
Linux命令的

是:

grep -r "string to be searched" .

答案 15 :(得分:3)

在我的IBM AIX服务器(操作系统版本:AIX 5.2)中,使用:

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

这将在文件中打印出路径/文件名和相对行号,如:

./ INC / xxxx_x.h

2865:/ **描述:stringYouWannaFind * /

无论如何,它对我有用:)

答案 16 :(得分:2)

我想这就是你要写的东西

grep myText $(find .)

如果你想找到grep hit

这些文件,这可能会有所帮助
grep myText $(find .) | cut -d : -f 1 | sort | uniq

答案 17 :(得分:2)

有关可用标志的列表:

grep --help 

返回当前目录中regexp texthere 的所有匹配项,以及相应的行号:

grep -rn "texthere" .

返回 texthere 的所有匹配项,从根目录开始,使用相应的行号并忽略大小写:

grep -rni "texthere" /

此处使用的标志:

  • -r recursive
  • -n打印包含输出的行号
  • -i忽略大小写

答案 18 :(得分:2)

在2018年,您希望使用ripgrepthe-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

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

答案 19 :(得分:1)

请注意,find . -type f | xargs grep whatever种解决方案会在&#34;参数列表中长到&#34;当找到匹配的文件太多时出错。

最好的选择是grep -r,但如果不可用,请改用find . -type f -exec grep -H whatever {} \;

答案 20 :(得分:1)

只是为了好玩,如果@christangrant答案太多而无法输入,请快速搜索* .txt文件: - )

grep -r texthere .|grep .txt

答案 21 :(得分:1)

把我的两分钱丢在这里。正如其他人已经提到的那样, grep -r 并非在所有平台上都适用。这听起来很傻,但是我总是使用git。

git grep "texthere"

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

答案 22 :(得分:0)

这是一个递归(轻轻地用bash和sh测试)函数遍历给定文件夹的所有子文件夹($ 1)并使用grep搜索给定文件中的给定字符串($ 3)($ 2):

$ cat script.sh
#!/bin/sh

cd "$1"

loop () {
    for i in *
    do
        if [ -d "$i" ]
        then
            # echo entering "$i"
            cd "$i"
            loop "$1" "$2"
        fi
    done

    if [ -f "$1" ]
    then
        grep -l "$2" "$PWD/$1"
    fi

    cd ..
}

loop "$2" "$3"

运行它并输出示例:

$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename

答案 23 :(得分:0)

对于.gz文件,以递归方式扫描所有文件和目录 更改文件类型或放置*

find . -name \*.gz -print0 | xargs -0 zgrep "STRING"

答案 24 :(得分:0)

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

grep -irn "string" /

显示大量结果,因此您可能需要通过管道过滤输出

答案 25 :(得分:-2)

The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .