如何在Linux上找到包含特定文本的所有文件?
我正在尝试找到一种方法来扫描整个Linux系统,查找包含特定文本字符串的所有文件。 只是为了澄清,我在文件中寻找文本,而不是文件名。
当我查找如何做到这一点时,我遇到了两次这个解决方案:
find / -type f -exec grep -H 'text-to-find-here' {} ;
但是,它不起作用。 它似乎显示系统中的每个文件。
这是否接近正确的方法呢? 如果没有,我该怎么办? 这种在文件中查找文本字符串的能力对于我正在做的一些编程项目非常有用。
#1楼
你可以使用grep -ilR
:
grep -Ril "text-to-find-here" /
-
i
代表忽略大小写(在你的情况下是可选的)。 -
R
代表递归。 -
l
代表“显示文件名,而不是结果本身”。 -
/
表示从机器的根目录开始。
#2楼
请执行下列操作:
grep -rnw '/path/to/somewhere/' -e 'pattern'
-
-r
或-R
是递归的, -
-n
是行号,和 -
-w
代表整个单词的匹配。 - 可以添加
-l
(小写L)以仅提供匹配文件的文件名。
除此之外, - --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
。
#3楼
你可以使用ack 。 它就像grep的源代码。 您可以使用它扫描整个文件系统。
做就是了:
ack 'text-to-find-here'
在根目录中。
您还可以使用正则表达式 ,指定文件类型等。
UPDATE
我刚刚发现了The Silver Searcher ,它类似于ack但比它快3-5倍,甚至忽略了.gitignore
文件中的模式。
#4楼
你可以用这个:
grep -inr "Text" folder/to/be/searched/
#5楼
包含给定文本的文件名列表
首先,我相信您使用了-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
开关忽略大小写。 您可以在此处详细信息
希望这对你有所帮助。
#6楼
我写了一个Python脚本 ,它做了类似的事情。 这就是人们应该如何使用这个脚本。
./sniff.py path pattern_to_search [file_pattern]
第一个参数path
是递归搜索的目录。 第二个参数pattern_to_search
是我们想要在文件中搜索的正则表达式。 我们使用Python re
库中定义的正则表达式格式。 在这个脚本中, .
也匹配换行。
第三个参数file_pattern
是可选的。 这是另一个适用于文件名的正则表达式。 仅考虑与此正则表达式匹配的那些文件。
例如,如果我想搜索扩展名py
包含Pool(
Python文件Pool(
后跟单词Adaptor
,我会执行以下操作,
./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
瞧,它会生成匹配文件的路径和找到匹配项的行号。 如果找到多个匹配项,则每个行号将附加到文件名。
#7楼
要搜索字符串并使用搜索字符串输出该行:
for i in $(find /path/of/target/directory -type f); do grep -i "the string to look for" "$i"; done
例如:
for i in $(find /usr/share/applications -type f);
do grep -i "web browser" "$i"; done
要显示包含搜索字符串的文件名:
for i in $(find /path/of/target/directory -type f); do if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;
例如:
for i in $(find /usr/share/applications -type f);
do if grep -i "web browser" "$i" > /dev/null; then echo "$i";
fi; done;
#8楼
以下是可用于搜索文件的几个命令列表。
grep "text string to search” directory-pathgrep [option] "text string to search” directory-pathgrep -r "text string to search” directory-pathgrep -r -H "text string to search” directory-pathegrep -R "word-1|word-2” directory-pathegrep -w -R "word-1|word-2” directory-path
#9楼
您可以使用:
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“要搜索的字符串”/ path /到/ directory /或/ file -r:递归搜索 n:将显示匹配的行号
#10楼
即使我们没有找到字符串,也可以使用grep
。
只需跑步,
grep -RIl "" .
将打印出所有文本文件的路径,即仅包含可打印字符的文件。
#11楼
如果你的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
- 只输出匹配的行(不是文件名)
#12楼
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
#13楼
尝试:
find . -name "*.txt" | xargs grep -i "text_pattern"
#14楼
试试这个:
find . | xargs grep 'word' -sl
#15楼
希望这有助于......
稍微扩展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
OR*.dfm
文件,或者用-o
指定 -
-type f
指定您正在查找文件 -
-print0
和--null
上的另一边|
(管道)是关键的,将文件名从find
发送到嵌入在xargs
的grep
,允许在文件名中传递带有空格的文件名,允许grep将路径和文件名视为一个字符串,而不是破坏它在每个空间。
#16楼
尝试:
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' {} ;
#17楼
grep
( GNU或BSD )
您可以使用grep
工具递归搜索当前文件夹,如:
grep -r "class foo" .
注意: -r
- 递归搜索子目录。
您还可以使用通配语法在特定文件中进行搜索,例如:
grep "class foo" **/*.c
注意:通过使用globbing选项 ( **
),它以递归方式扫描具有特定扩展名或模式的所有文件。要启用此语法,请运行: shopt -s globstar
。您也可以对所有文件使用**/*.*
(隐藏和不扩展除外)或任何其他模式。
如果您的错误是您的参数太长,请考虑缩小搜索范围,或使用find
语法,例如:
find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'
或者使用ripgrep
。
ripgrep
如果你正在处理更大的项目或大文件,你应该使用ripgrep
,比如:
rg "class foo" .
查看GitHub项目页面上的文档,安装步骤或源代码。
它比任何其他工具(如GNU / BSD grep
, ucg
, ag
, sift
, ack
, pt
或类似工具)快得多,因为它建立在Rust的正则表达式引擎之上,该引擎使用有限自动机,SIMD和积极的文字优化来快速搜索。
它支持忽略.gitignore
文件中指定的模式,因此可以同时将单个文件路径与多个glob模式进行匹配。
您可以使用常用参数,例如:
-
-i
- 不敏感的搜索。 -
-I
- 忽略二进制文件。 -
-w
- 搜索整个单词(与部分单词匹配相反)。 -
-n
- 显示您的匹配项。 -
-C
/--context
(如-C5
) -增加背景下,让你看到周围的代码。 -
--color=auto
- 标记匹配的文本。 -
-H
- 显示找到文本的文件名。 -
-c
- 显示匹配行的数量。 可与-H
组合使用。
#18楼
如何在Linux上找到包含特定文本的所有文件? (......)
我两次遇到这个解决方案:
find / -type f -exec grep -H 'text-to-find-here' {} \;
如果使用发现就像在你的榜样,最好加-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 'text-to-find-here' / -l
注意:您也可以向这些命令添加2>/dev/null
,以隐藏许多错误消息。
警告 : 除非你真的无法避免它,否则不要在'/' (根目录)中搜索以避免长时间和低效的搜索! 因此,在上面的示例中,您最好用子目录名替换' / ',例如“/ home”取决于您实际想要搜索的位置...
#19楼
以下命令适用于此方法:
find ./ -name "file_pattern_name" -exec grep -r "pattern" {} ;
#20楼
grep -insr "pattern" *
-
i
:忽略PATTERN和输入文件中的大小写区别。 -
n
:在输入文件中使用从1开始的行号为每行输出添加前缀。 -
s
:禁止有关不存在或不可读文件的错误消息。 -
r
:递归读取每个目录下的所有文件。
#21楼
避免麻烦并安装ack-grep。 它消除了许多许可和报价问题。
apt-get install ack-grep
然后转到要搜索的目录并运行以下命令
cd /
ack-grep "find my keyword"
#22楼
使用pwd
从您所在的任何目录中搜索,向下递归
grep -rnw `pwd` -e "pattern"
更新根据您使用的grep版本,您可以省略pwd
。 在较新的版本上.
如果没有给出目录,似乎是grep的默认情况:
grep -rnw -e "pattern"
要么
grep -rnw "pattern"
会做同上面的事情!
#23楼
有一个ack
工具可以完全满足您的需求。
http://linux.die.net/man/1/ack
ack -i search_string folder_path/*
您可以忽略-i
用于区分大小写的搜索
#24楼
有一个名为The Silversearcher的新工具
sudo apt install silversearcher-ag
它与Git和其他VCS密切合作。 所以你不会在.git或其他目录中获得任何东西。
你可以简单地使用
ag "Search query"
它会为你完成任务!
#25楼
Silver Searcher是一个了不起的工具,但ripgrep可能会更好。
它可以在Linux,Mac和Windows上运行,并且在几个月前写在Hacker News上 (这有一个链接到Andrew Gallant的Blog,它有一个GitHub链接):
Ripgrep - 一种新的命令行搜索工具
#26楼
使用:
grep -c Your_Pattern *
这将报告当前目录中每个文件中有多少个模式副本。
#27楼
一个简单的find
可以很方便。 在~/.bashrc
文件中将其别名:
alias ffind find / -type f | xargs grep
启动新终端并发出:
ffind 'text-to-find-here'
#28楼
所有以前的答案都建议grep并找到。 但还有另一种方法:使用午夜指挥官
它是一个免费的实用程序(30岁,经过时间证明),它是视觉上没有GUI。 它有很多功能,查找文件只是其中之一。
#29楼
我很着迷于grep用'rl'做出的简单方法
grep -rl 'pattern_to_find' /path/where/to/find-r to find recursively file / directory inside directories..
-l to list files matching the 'pattern'
使用'-r'而不是'l'来查看文件名后面跟着找到模式的文本 !
grep -r 'pattern_to_find' /path/where/to/find
工作得很完美..
希望能帮助到你!
#30楼
grep是你实现这一目标的好朋友。
grep -r <text_fo_find> <directory>
如果你不关心文本的情况下找到然后使用
grep -ir <text_to_find> <directory>