如何递归地grep
所有目录和子目录?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
在 Redhat Linux 上不适合我。我收到“不匹配”错误。
grep -r "texthere" .
第一个参数代表要搜索的正则表达式,而第二个参数代表应该搜索的目录。在这种情况下,.
表示当前目录。
注意:这适用于 GNU grep,并且在 Solaris 等某些平台上,您必须专门使用 GNU grep 而不是传统实现。对于 Solaris,这是 ggrep
命令。
如果您知道想要的文件的扩展名或模式,另一种方法是使用 --include
选项:
grep -r --include "*.txt" texthere .
您还可以使用 --exclude
提及要排除的文件。
银
如果您经常搜索代码,Ag (The Silver Searcher) 是 grep 更快的替代方法,它是为搜索代码而定制的。例如,默认情况下它是递归的,并自动忽略 .gitignore
中列出的文件和目录,因此您不必一直将相同的繁琐排除选项传递给 grep 或 find。
=
在 Ubuntu 上工作得很好。 PS:这应该是一个反引号的空间,但是 SO Markdown 解析器失败了。
grep
,而不是 Ag,你知道 :)
--include "*.txt" --include "*.TXT"
我现在总是使用(即使在带有 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
用输入文件中的行号为每行输出添加前缀。
(注意:phuclv 将 in 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;
...
-R
选项递归)应用于文件夹。
*
或 .
是一个 glob 模式(由 shell 解释):unix.stackexchange.com/a/64695/7490。 “.
”也会选择点文件或点文件夹(如 .git/
)
还:
find ./ -type f -print0 | xargs -0 grep "foo"
但 grep -r
是一个更好的答案。
find . -type f -exec grep "foo" '{}' \;
在受支持的情况下也能正常工作。
find ./ -type f -print0 | xargs -0 grep "foo"
通配符**
使用 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。
在 POSIX 系统中,您找不到 grep
的 -r
参数,并且您的 grep -rn "stuff" .
不会运行,但如果您使用 find
命令,它将:
find . -type f -exec grep -n "stuff" {} \; -print
Solaris
和 HP-UX
同意。
-exec
选项中 - 符号 {}
是对 find
工具当前找到的文件名的引用(即对我们找到的文件名做一些事情),同样 -exec
选项应该以 ;
符号终止(标记 exec 命令的结束),但是因为这一切都在 shell 中运行,所以符号应该被转义.. 最后 -print
选项让 find
工具在屏幕上打印出找到的文件名。
如果您只想关注实际目录而不是符号链接,
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/
要查找 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
只是文件名也很有用
grep -r -l "foo" .
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
这应该有效:
grep -R "texthere" *
如果您要在目录结构的所有文件中查找特定内容,则可以使用 find
,因为它更清楚您在做什么:
find -type f -exec grep -l "texthere" {} +
请注意,-l
(L 的小写)显示包含文本的文件的名称。如果您想打印匹配本身,请将其删除。或使用 -H
将文件与匹配项一起获取。总之,其他选择是:
find -type f -exec grep -Hn "texthere" {} +
其中 -n
打印行号。
find
解决方案,以避免不必要地使用 xargs
并使用 +
而不是 \;
和 -exec
,从而避免大量不必要的进程启动。 :-)
这是适用于我当前机器上的案例的一个(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"
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)
在 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
在 OSX 上,这会安装 ripgrep
: brew install ripgrep
。这将安装 silver-searcher
: brew install the_silver_searcher
。
rg
也比从头开始拼凑一个递归 grep 命令具有相当大的优势。使用 rg
:rg foo
。使用 unix 工具:find . | xargs grep foo
。如果您的任何文件中包含引号,则需要使用 find . -print0 | xargs -0 grep foo
。如果你每年使用几次,你会记得吗?
find . -type f -exec grep 'regex' {} +
,如果您经常使用这些工具,这确实很容易记住。但是,如果您需要经常查找内容,您可能应该在源代码树上运行 ctags
或 etags
。
把我的两分钱扔在这里。正如其他人已经提到的那样, grep -r 并不适用于每个平台。这听起来可能很傻,但我总是使用 git。
git grep "texthere"
即使目录没有暂存,我也只是暂存它并使用 git grep。
递归地在 Linux 系统上的所有文件中 grep 字符串的另一种语法
grep -irn "string" /
显示大量结果,因此您可能需要通过管道过滤输出
在我的 IBM AIX Server(操作系统版本:AIX 5.2)中,使用:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
这将打印出文件中的路径/文件名和相对行号,例如:
./inc/xxxx_x.h
2865:/** 描述:stringYouWannaFind */
无论如何,它对我有用:)
以下是在 Unix
和 Linux
环境中递归搜索 String
的命令。
UNIX
命令是:
find . -name "string to be searched" -exec grep "text" "{}" \;
Linux
命令是:
grep -r "string to be searched" .
我想这就是你想要写的
grep myText $(find .)
如果您想查找 grep 命中的文件,这可能会有所帮助
grep myText $(find .) | cut -d : -f 1 | sort | uniq
有关可用标志的列表:
grep --help
返回当前目录中正则表达式 texthere 的所有匹配项,并带有相应的行号:
grep -rn "texthere" .
返回 texthere 的所有匹配项,从根目录开始,带有相应的行号并忽略大小写:
grep -rni "texthere" /
此处使用的标志:
-r 递归
-n 打印带有输出的行号
-i 忽略大小写
请注意,当 find 匹配的文件过多时,find . -type f | xargs grep whatever
种解决方案会遇到“Argument list to long”错误。
最好的选择是 grep -r
,但如果它不可用,请改用 find . -type f -exec grep -H whatever {} \;
。
xargs
专门用于解决“参数列表太长”问题。
find . -type f | xargs -L 100 grep whatever
xargs
已标准化以使此行为开箱即用。 “xargs
实用程序应限制命令行长度,以便在调用命令行时,组合的参数和环境列表...不应超过 {ARG_MAX}-2048 字节。”
对于 .gz 文件,递归扫描所有文件和目录 更改文件类型或放 *
find . -name \*.gz -print0 | xargs -0 zgrep "STRING"
只是为了好玩,如果@christangrant 答案太多而无法输入,则快速而肮脏地搜索 *.txt 文件:-)
grep -r texthere .|grep .txt
这是一个递归(使用 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
The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .
AIX 5.3
附带的 grep。