ChatGPT解决这个技术问题 Extra ChatGPT

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

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

find . | xargs grep "texthere" *
@TC1 可悲的是 grep 本身可以回答这个问题(至少是 GNU grep): grep --help |grep recursive
如果您发现自己经常使用 grep 进行递归搜索(尤其是如果您手动执行大量文件/目录排除),您可能会发现 ack(一个非常适合程序员的 grep 替代方案)很有用。
实际上,我在工作中使用的 Solaris 机器上既没有 -r 也没有 --recursive 工作。 grep 的手册页没有提到任何递归。我不得不自己寻找和xargs。
ag 是我现在最喜欢的方法github.com/ggreer/the_silver_searcher
grep -rin xlsx *.pl 在 Redhat Linux 上不适合我。我收到“不匹配”错误。

G
Greg Bacon
grep -r "texthere" .

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

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


注意:“grep -r”仅适用于较新的 grep。例如,它不适用于 AIX 5.3 附带的 grep。
使用 grep -R 跟踪符号链接。
很高兴知道“-i”会使其不区分大小写,“-n”还包括每个匹配结果的行号。
也很高兴知道,如果您只是在寻找固定字符串而不是正则表达式,请使用 -F 选项。通过不调用正则表达式解析器,它将为您节省大量时间。如果您要搜索大量文件,则非常方便。
别名 rgrep='grep -r'
D
Dan Dascalescu

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

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

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

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


与 Linux 和 Cygwin 附带的 grep 配合使用效果很好,但不适用于 AIX 附带的 grep。
@KrzysztofWolny:` ` 而不是 = 在 Ubuntu 上工作得很好。 PS:这应该是一个反引号的空间,但是 SO Markdown 解析器失败了。
@DanDascalescu 我赞成 grep,而不是 Ag,你知道 :)
我们是否可以选择在递归搜索时排除目录?
Windows cygwin 喜欢双引号 --include "*.txt" --include "*.TXT"
V
VonC

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

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

(如 the comments 中的 kronen 所述,您可以添加 2>/dev/null 以使权限被拒绝输出无效)

这包括以下选项:

--include=PATTERN

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

-n, --line-number

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

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

-R, -r, --recursive

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

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

Gow 看起来很有希望——比我一直使用的 GNU Windows 实用程序更新。现在试试...
这里最后一个字符 * 是什么意思?
@lorniper 它使外壳程序选择当前目录中的所有文件和文件夹,从而使 grep 应用于这些文件并(由于 -R 选项递归)应用于文件夹。
@lorniper Noy 确切地说:*. 是一个 glob 模式(由 shell 解释):unix.stackexchange.com/a/64695/7490。 “.”也会选择点文件或点文件夹(如 .git/
以前我一直使用 grep -rnI,但后来我知道了 -n decreases performance a lot,所以我只在真正需要时使用它,通常我会使用 -rI
I
Iulian Onofrei

还:

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

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


或者,如果您不想担心文件名中的空格,find . -type f -exec grep "foo" '{}' \; 在受支持的情况下也能正常工作。
如果您打算通过 xargs 将 find 通过管道传输到 grep,并且如果您只搜索固定字符串(即,不是正则表达式),您可能会从调用 grep -F 选项中受益,因此 grep 不会加载正则表达式引擎每次调用。如果有很多文件,它会快得多。
寻找 。 -type f -exec grep -Hu "foo" {} \;是我使用的,因为它给出了文件名。
这适用于所有 *nix,因为它是 POSIX 7
find ./ -type f -print0 | xargs -0 grep "foo"
k
kenorb

通配符**

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

为了更实际的使用,这里是使用 globbing syntax (**) 的语法:

grep "texthere" **/*.txt

它仅对具有模式选择模式的特定文件进行 greps。它适用于受支持的 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

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

rg "pattern" .

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


感谢 git grep 的建议——它非常有用,我不知道!
感谢 ripgrep 的建议。它的速度更快。
r
rook

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

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

SolarisHP-UX 同意。


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

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

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

并且您想要捕获文件名而不是字符串“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/


很好的答案。额外的开关 (-rnh) 非常有用,因此感谢您提出建议。
G
Girdhar Singh Rathore

要查找 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

c
chim

只是文件名也很有用

grep -r -l "foo" .

C
Community

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

s
sashkello

这应该有效:

grep -R "texthere" *

f
fedorqui

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

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

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

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

其中 -n 打印行号。


投票赞成作为唯一的 find 解决方案,以避免不必要地使用 xargs 并使用 + 而不是 \;-exec,从而避免大量不必要的进程启动。 :-)
a
arkod

这是适用于我当前机器上的案例的一个(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"


C
Community

grep -r "texthere" . (通知期结束)

(^信用:https://stackoverflow.com/a/1987928/1438029

澄清:

grep -r "texthere" /(递归 grep all 目录和子目录)

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

grep 递归

grep [options] PATTERN [FILE...] [options] -R, -r, --recursive 递归读取每个目录下的所有文件。这等效于 -d recurse 或 --directories=recurse 选项。 http://linuxcommand.org/man_pages/grep1.html

grep 帮助

$ grep --help

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

备择方案

ack (http://beyondgrep.com/)

ag (http://github.com/ggreer/the_silver_searcher)


h
hughdbrown

在 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 上,这会安装 ripgrep: brew install ripgrep。这将安装 silver-searcher: brew install the_silver_searcher


如果您需要经常这样做,速度很重要,但我们大多数人发现自己一年最多只这样做几次。安装最新的漂亮的第三方 juju 工具 du jour 是多余的,而且自 1978 年以来没有太大变化的解决方案无论如何都值得了解。
我发现程序员每年只在源代码树中搜索几次文本是非常难以置信的。但即使从可用性的角度来看,rg 也比从头开始拼凑一个递归 grep 命令具有相当大的优势。使用 rgrg foo。使用 unix 工具:find . | xargs grep foo。如果您的任何文件中包含引号,则需要使用 find . -print0 | xargs -0 grep foo。如果你每年使用几次,你会记得吗?
您忘记了find . -type f -exec grep 'regex' {} +,如果您经常使用这些工具,这确实很容易记住。但是,如果您需要经常查找内容,您可能应该在源代码树上运行 ctagsetags
我一直在使用 ripgrep,它很棒。但银牌搜索器对程序员来说非常棒。 +1
Z
Zstack

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

git grep "texthere"

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


g
geek

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

grep -irn "string" /

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


u
user3606336

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

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

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

./inc/xxxx_x.h

2865:/** 描述:stringYouWannaFind */

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


G
Girdhar Singh Rathore

以下是在 UnixLinux 环境中递归搜索 String 的命令。

UNIX 命令是:

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

Linux 命令是:

grep -r "string to be searched" .

V
Victor Faria

我想这就是你想要写的

grep myText $(find .)

如果您想查找 grep 命中的文件,这可能会有所帮助

grep myText $(find .) | cut -d : -f 1 | sort | uniq

它非常直观:例如: grep -i acc $(find . -name "execution*.*")
J
JSON C11

有关可用标志的列表:

grep --help 

返回当前目录中正则表达式 texthere 的所有匹配项,并带有相应的行号:

grep -rn "texthere" .

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

grep -rni "texthere" /

此处使用的标志:

-r 递归

-n 打印带有输出的行号

-i 忽略大小写


m
m.thome

请注意,当 find 匹配的文件过多时,find . -type f | xargs grep whatever 种解决方案会遇到“Argument list to long”错误。

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


嗯? xargs 专门用于解决“参数列表太长”问题。
嗯,不 - xargs 专门用于将参数管道转换为 arglist,但是是的,现代 xargs 当与 -s 和/或 -L 一起使用时可以通过分解为多个命令调用来处理非常长的参数列表,但默认情况下它没有这样配置(并且不在上述任何响应中)。例如:find . -type f | xargs -L 100 grep whatever
那会在哪个平台上? POSIX xargs 已标准化以使此行为开箱即用。 xargs 实用程序应限制命令行长度,以便在调用命令行时,组合的参数和环境列表...不应超过 {ARG_MAX}-2048 字节。”
嗯。虽然在此基础上 gnu 文档不如 posix 清晰,并且我不再有权访问导致我发表此声明的机器,但我无法确认我对任何当前实现的原始解释。当然,如果可用,递归 grep 仍然是可取的,但是没有理由避免使用 xargs 配方(请使用 -H 作为 grep 以避免最终调用 grep 只传递一个文件名)。
S
Shreesh Mohan Verma

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

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

P
PJ Brunet

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

grep -r texthere .|grep .txt


J
James Brown

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

$ 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

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

这并没有增加其他答案