想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。
如何在文件内容中找到包含特定文本字符串的所有文件?
以下不起作用。它似乎显示了系统中的每个文件。
find / -type f -exec grep -H 'text-to-find-here' {} \;
.
解释为单字符通配符等。我的建议是始终使用 fgrep 或 egrep。
-H
替换为 -l
(也可以将 grep
替换为 fgrep
)。要排除具有特定名称模式的文件,您可以使用 find
以更高级的方式。不过,学习使用 find
是值得的。只需 man find
。
find … -exec <cmd> +
比 find … -exec <cmd> \;
更容易输入且速度更快。它仅在 <cmd>
接受任意数量的文件名参数时才有效。如果 <cmd>
像 Python 或 Ruby 脚本一样启动缓慢,则执行时间的节省尤其大。
请执行下列操作:
grep -rnw '/path/to/somewhere/' -e 'pattern'
-r 或 -R 是递归的,
-n 是行号,并且
-w 代表匹配整个单词。
-l(小写 L)可以添加以仅给出匹配文件的文件名。
-e 是搜索过程中使用的模式
除了这些,--exclude
、--include
、--exclude-dir
标志可用于高效搜索:
这只会搜索具有 .c 或 .h 扩展名的文件:
grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
这将排除搜索所有以 .o 扩展名结尾的文件:
grep --exclude=\*.o -rnw '/path/to/somewhere/' -e "pattern"
对于目录,可以使用 --exclude-dir 参数排除一个或多个目录。例如,这将排除目录 dir1/、dir2/ 以及所有匹配 *.dst/ 的目录:
grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
这对我来说非常有效,可以实现与您几乎相同的目的。
有关更多选项,请参阅 man grep
。
使用 grep -ilR
:
grep -Ril "text-to-find-here" /
i 代表忽略大小写(在您的情况下是可选的)。
R代表递归。
l 代表“显示文件名,而不是结果本身”。
/ 代表从机器的根目录开始。
-i
会使它变慢很多,所以如果没有必要就不要使用它。在某个目录中对其进行测试,然后进行概括。它应该在几分钟内完成。我认为正则表达式会使它变慢。但是我的评论是基于假设的,我建议您在行前使用 time
进行测试。
/*
代表它。无论如何,我刚刚对其进行了测试,发现只有 /
有效。
fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings
。
grep -Ril "text-to-find-here" ~/sites/
的路径或使用 .当前目录 grep -Ril "text-to-find-here" .
您可以使用 ack。它类似于源代码的 grep。您可以使用它扫描整个文件系统。
做就是了:
ack 'text-to-find-here'
在您的根目录中。
您还可以使用 regular expressions,指定文件类型等。
更新
我刚刚发现 The Silver Searcher,它类似于 ack,但比它快 3-5 倍,甚至忽略了 .gitignore
文件中的模式。
您可以使用:
grep -r "string to be searched" /path/to/dir
r
代表递归,因此将在指定的路径及其子目录中进行搜索。这将告诉您文件名并打印出文件中出现字符串的行。
或类似于您正在尝试的命令(例如:)在所有 javascript 文件 (*.js) 中搜索:
find . -name '*.js' -exec grep -i 'string to search for' {} \; -print
这将打印文件中出现文本的行,但不打印文件名。
除了这个命令,我们也可以这样写: grep -rn "String to search" /path/to/directory/or/file -r: recursive search n: 将显示匹配的行号
带有行号的递归和不区分大小写的 grep:
grep -inr "Text" folder/to/be/searched/
grep(GNU 或 BSD)
您可以使用 grep
工具递归搜索当前文件夹,例如:
grep -r "class foo" .
注意:-r
- 递归搜索子目录。
您还可以使用通配符语法在特定文件中进行搜索,例如:
grep "class foo" **/*.c
注意:通过使用 globbing option (**
),它递归地扫描具有特定扩展名或模式的所有文件。 要启用此语法,请运行:shopt -s globstar
。您还可以将 **/*.*
用于所有文件(不包括隐藏且无扩展名)或任何其他模式。
如果您遇到参数太长的错误,请考虑缩小搜索范围,或改用 find
语法,例如:
find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'
或者,使用 ripgrep
。
ripgrep
如果您正在处理较大的项目或大文件,则应改用 ripgrep
,例如:
rg "class foo" .
查看 GitHub project page 上的文档、安装步骤或源代码。
它比任何其他工具(如 GNU/BSD grep
、ucg
、ag
、sift
、ack
、pt
或类似工具都快得多,因为它构建在 {9 之上它使用有限自动机、SIMD 和积极的文字优化来使搜索非常快速。
它支持在 .gitignore
文件中指定的忽略模式,因此单个文件路径可以同时与多个 glob 模式匹配。
您可以使用常用参数,例如:
-i - 不敏感搜索。
-I - 忽略二进制文件。
-w - 搜索整个单词(与部分单词匹配相反)。
-n - 显示匹配的行。
-C/--context (eg -C5) - 增加上下文,所以你可以看到周围的代码。
--color=auto - 标记匹配的文本。
-H - 显示找到文本的文件名。
-c - 显示匹配行数。可以与 -H 结合使用。
包含给定文本的文件名列表
首先,我相信您使用的是 -H
而不是 -l
。您也可以尝试在引号内添加文本,后跟 {} \
。
find / -type f -exec grep -l "text-to-find-here" {} \;
例子
假设您正在目录中搜索包含特定文本“Apache License”的文件。它将显示类似于下面的结果(输出将根据您的目录内容而有所不同)。
bash-4.1$ find . -type f -exec grep -l "Apache License" {} \;
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$
删除区分大小写
即使您不使用“text”与“TEXT”之类的大小写,也可以使用 -i
开关忽略大小写。您可以阅读更多详细信息here。
希望这对您有所帮助。
find
会将它找到的所有路径传递给命令 grep -l "text-to-find-here" <file found>"
。您可以对文件名添加限制,例如 find / -iname "*.txt"
只搜索名称以 .txt
结尾的文件
-iname
不区分大小写,这意味着它还会找到 .TXT 文件,例如,以及 TxT 和 TXt 等。
当您在 Linux 上搜索特定文本时,此 grep 命令将为您提供精确的结果 -
grep -inRsH "Text to be searched" /path/to/dir (it can be '.')
i 代表忽略大小写区别
代表递归,它还包括符号链接。最好使用“R”而不是“r”
代表“它将打印行号”。
s 代表“抑制错误消息”
H 代表“它将打印每个匹配的文件名”
如果您的 grep
不支持递归搜索,您可以将 find
与 xargs
结合起来:
find / -type f | xargs grep 'text-to-find-here'
我发现这比 find -exec
的格式更容易记住。
这将输出匹配行的文件名和内容,例如
/home/rob/file:text-to-find-here
您可能要添加到 grep
的可选标志:
-i - 不区分大小写的搜索
-l - 只输出找到匹配的文件名
-h - 只输出匹配的行(不是文件名)
find
没有找到任何内容,这相当于没有文件名的 grep 'text-to-find-here'
。这将挂起并等待用户输入!将 --no-run-if-empty
作为选项添加到 xargs
。
find … -exec grep … +
。如果您坚持将 find 与 xargs 一起使用,请使用 -print0
和 -0
。
grep -insr "pattern" *
i:忽略 PATTERN 和输入文件中的大小写区别。
n:在其输入文件中使用从 1 开始的行号作为每行输出的前缀。
s:抑制有关不存在或不可读文件的错误消息。
r:递归读取每个目录下的所有文件。
有一个名为 The Silversearcher 的新实用程序
sudo apt install silversearcher-ag
它与 Git 和其他 VCS 密切合作。所以你不会在 .git 或其他目录中得到任何东西。
你可以简单地使用
ag "Search query"
它会为你完成任务!
如何在 Linux 上找到包含特定文本的所有文件? (...) 我两次遇到这个解决方案: find / -type f -exec grep -H 'text-to-find-here' {} \;
如果在您的示例中使用 find,最好将 -s
(--no-messages
) 添加到 grep
,并在命令末尾添加 2>/dev/null
以避免大量 权限grep
和 find
发出的拒绝消息:
find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null
find 是在类 Unix 平台上搜索文件的标准工具 - 在查找特定文本时与 grep 结合使用。顺便说一下,find 命令通常与 xargs 结合使用。
出于相同目的,存在更快、更简单的工具 - 见下文。最好尝试一下,前提是它们可以在您的平台上使用,当然:
更快更简单的替代方案
RipGrep - 最快的搜索工具:
rg 'text-to-find-here' / -l
ag 'text-to-find-here' / -l
ack:
ack 'text-to-find-here' / -l
注意:您也可以将 2>/dev/null
添加到这些命令中,以隐藏许多错误消息。
警告:除非你真的无法避免,否则不要从 '/' (the root directory) 搜索,以免搜索时间长且效率低!因此,在上面的示例中,您最好将“/”替换为子目录名称,例如“/home”,具体取决于您实际要搜索的位置...
尝试:
find . -name "*.txt" | xargs grep -i "text_pattern"
xargs
这样的一个主要示例.. 考虑一下。 echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo
。此处的 xargs
与错误文件匹配,与预期文件不匹配。要么使用 find .. -print0 | xargs -0 ...
,但这是无用的管道或更好的 find ... -exec grep ... {} +
grep -lrnw '/root/Desktop/ipozal' -e 'geolocation'
例如:
我的文件夹名称是“ipozal”
它放在“/root/Desktop”上
我想在“地理位置”中的所有文件上找到此文本
使用 pwd
从您所在的任何目录中搜索,向下递归
grep -rnw `pwd` -e "pattern"
更新 根据您使用的 grep 版本,您可以省略 pwd
。如果没有给出目录,则在较新的版本上 .
似乎是 grep 的默认情况:
grep -rnw -e "pattern"
或者
grep -rnw "pattern"
会做和上面一样的事情!
pwd
,因为它是默认设置。 grep -rnw "pattern"
就足够了。
grep -rnw
和类似的答案就像三年前一样,我看不出这个答案是如何增加价值的。
grep -rnw '/path/to/somewhere/' -e "pattern"
,这就是您在此处所拥有的。 230 万次访问后获得 5 票并不意味着什么。
即使我们不是在寻找字符串,也可以使用 grep
。
简单的跑步,
grep -RIl "" .
将打印出所有文本文件的路径,即那些只包含可打印字符的文件。
ls
或 find
(用于递归)更好
如果您严格要使用 find
,请使用 find + grep
:
find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;
脚步:
使用 find 搜索文件,对所有文件执行 grep。
这使您可以使用 find
查找文件。
如果您只想 grep 某些文件,请使用 -name Pattern:
find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;
您可以使用 find
的不同选项来改进文件搜索。
以下是可用于搜索文件的几个命令列表。
grep "text string to search” directory-path
grep [option] "text string to search” directory-path
grep -r "text string to search” directory-path
grep -r -H "text string to search” directory-path
egrep -R "word-1|word-2” directory-path
egrep -w -R "word-1|word-2” directory-path
Silver Searcher 是一个了不起的工具,但 ripgrep 可能会更好。
它适用于 Linux、Mac 和 Windows,几个月前在 Hacker News 上写过(这里有 Andrew Gallant 博客的链接,其中有一个 GitHub 链接):
Ripgrep – A new command line search tool
如果您在 Git 存储库中,则可以使用:
git grep something
git
和/或未签入 .gitignore
文件的文件?只是检查以确保,因为我喜欢在目录已经是 git
存储库的大多数开发情况下这是多么方便。
我对 grep 使用 'rl' 的简单程度着迷:
grep -rl 'pattern_to_find' /path/where/to/find
-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'
使用不带 'l' 的 '-r' 来查看文件名,后跟找到模式的文本!
grep -r 'pattern_to_find' /path/where/to/find
它工作得非常完美......
.txt
)。或者有没有办法做到这一点?
希望这对您有帮助...
稍微扩展 grep
以在输出中提供更多信息,例如,获取文本所在文件中的行号,可以按如下方式完成:
find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"
如果您知道文件类型是什么,您可以通过指定要搜索的文件类型扩展名来缩小搜索范围,在本例中为 .pas
或 .dfm
文件:
find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"
选项的简短说明:
.在 find 中指定从当前目录。 -name "*.*" :对于所有文件( -name "*.pas" -o -name "*.dfm" ):仅 *.pas 或 *.dfm 文件,或使用 -o -type f 指定您在 | 的另一侧寻找文件 -print0 和 --null (pipe) 是关键,将文件名从 find 传递给嵌入在 xargs 中的 grep,允许在文件名中传递带有空格的文件名,允许 grep 将路径和文件名视为一个字符串,而不是破坏它在每个空间上。
-name '*.*'
不是您所说的;它不会拾取名为“文件”的文件,因为该模式不等同于该文件(没有 .ext);但是 *
会(除了 . 文件)。但是还有另一件事:如果您想要所有文件,为什么还要首先指定文件名?没有其他评论 - 除了很高兴知道仍然有人不使用 MS 术语“文件夹”(真的在说够之后我不会添加,但我想指出你所做的稍微不正确的陈述带有文件名 - 以及“全部”情况下的冗余/无用)。
grep "text-to-find-here" file_name
或者
grep "text-to-find-here" directory_path/*
如果要搜索当前目录:
grep "text-to-find-here" *
grep
之后添加一个 -r
开关。
find /path -type f -exec grep -l "string" {} \;
来自评论的解释
find 是一个命令,可让您在给定路径的子目录中查找文件和其他对象,例如目录和链接。如果您未指定文件名应满足的掩码,它将枚举所有目录对象。
-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename
尝试:
find / -type f -exec grep -H 'text-to-find-here' {} \;
它将搜索所有文件系统,因为 /
是根文件夹。
对于主文件夹使用:
find ~/ -type f -exec grep -H 'text-to-find-here' {} \;
对于当前文件夹使用:
find ./ -type f -exec grep -H 'text-to-find-here' {} \;
一个简单的 find
可以很方便地工作。在您的 ~/.bashrc
文件中为其命名:
alias ffind find / -type f | xargs grep
启动一个新终端并发出:
ffind 'text-to-find-here'
有一个 ack
工具可以完全满足您的需求。
http://linux.die.net/man/1/ack
ack -i search_string folder_path/*
对于区分大小写的搜索,您可以忽略 -i
grep 是您实现这一目标的好朋友。
grep -r <text_fo_find> <directory>
如果您不关心要查找的文本的大小写,请使用:
grep -ir <text_to_find> <directory>
-
,您需要先将 --
传递给 grep;否则会引起有趣的副作用!
我写了一个Python script,它做了类似的事情。这就是人们应该如何使用这个脚本。
./sniff.py path pattern_to_search [file_pattern]
第一个参数 path
是我们将在其中递归搜索的目录。第二个参数 pattern_to_search
是我们要在文件中搜索的正则表达式。我们使用 Python re
库中定义的正则表达式格式。在此脚本中,.
也匹配换行符。
第三个参数 file_pattern
是可选的。这是另一个适用于文件名的正则表达式。只有那些匹配这个正则表达式的文件才会被考虑。
例如,如果我想搜索扩展名为 py
且包含 Pool(
后跟单词 Adaptor
的 Python 文件,我执行以下操作,
./sniff.py . "Pool(.*?Adaptor" .*py
./Demos/snippets/cubeMeshSigNeur.py:146
./Demos/snippets/testSigNeur.py:259
./python/moose/multiscale/core/mumbl.py:206
./Demos/snippets/multiComptSigNeur.py:268
瞧,它会生成匹配文件的路径和找到匹配项的行号。如果找到多个匹配项,则每个行号都将附加到文件名中。
以前的所有答案都建议使用 grep 和 find。但还有另一种方法:使用 Midnight Commander
它是一个免费的实用程序(已有 30 年历史,已被时间证明),它是可视的,而不是 GUI。它有很多功能,查找文件只是其中之一。
不定期副业成功案例分享
r
选项是惰性的(首先遍历深度,而不是在第一个目录之后停止),而R
是贪婪的(将正确遍历整个树)。R
和r
都将正确遍历目录,但R
将遵循符号链接。