我正在尝试寻找一种方法来扫描整个Linux系统中包含特定文本字符串的所有文件。只是为了澄清一下,我在查找文件中的文本,而不是文件名中的文本。
当我查找如何执行此操作时,我遇到了两次此解决方案:
1
| find / -type f -exec grep -H 'text-to-find-here' {} \; |
但是,它不起作用。它似乎显示了系统中的每个文件。
这接近正确的方法吗?如果没有,我该怎么办?这种在文件中查找文本字符串的能力对于我正在做的一些编程项目非常有用。
- 记住,grep将把任何.解释为一个单字符通配符。我的建议是总是使用fgrep或egrep。
- 不管怎样,你就快到了!用-l代替-H(可能用grep代替fgrep)。为了排除具有特定模式名称的文件,您将以更高级的方式使用find。不过,学习使用find是很有价值的。就这样。
- find … -exec +比find … -exec \;更容易打字,速度更快。只有当接受任意数量的文件名参数时,它才起作用。如果启动起来像python或ruby脚本一样慢,那么执行时间的节省就特别大。
- 要在给定路径中非递归搜索,命令是'grep--include=*.txt-snw"pattern"the path/*。
- @我觉得你太复杂了。就说grep"pattern" path/*.txt。
- 这个问题应该在unix-linux社区中。
执行以下操作:
1
| grep -rnw '/path/to/somewhere/' -e 'pattern' |
- -r或-r是递归的,
- -n为行号,且
- -w代表匹配整个单词。
- 可以添加-l(小写L),只需给出匹配文件的文件名即可。
除此之外,还可以使用--exclude、--include、--exclude-dir标志进行有效搜索:
这对我来说非常有效,可以达到和你一样的目的。
更多选项请查看man grep。
- 但是,如何使它忽略二进制文件呢?
- 使用-排除。如"grep-rnw--exclude=*.o'directory'-e"模式
- 我发现grep的--include参数非常有用。例如:GRIP-RNW-包含= *.java。-E"我要找的东西"
- 这也有助于:jason4zhu.blogspot.jp/2014/10/test-post.html
- 如果它不起作用,请取消对目录的引用。另外,如果它是一个大目录,它可能只会挂一秒钟。不是瞬间的。
- 当试图找到"[email protected]"之类的东西时,它不起作用,它会返回到"email.com",但是一旦你在字符串中抛出(at)[@]符号,grep就会窒息并返回zip。
- 它很好用,但是如果我添加"-i"来忽略大小写,它会返回一些假结果。有人遇到同样的问题吗?
- 值得注意的是:似乎r选项是懒惰的(首先遍历深度,而不是在第一个目录之后停止),而r是贪婪的(将正确地遍历整个树)。
- 另外,请注意,它是区分大小写的。
- 嗨,一个幼稚的问题:为什么你在包括后使用*。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- @zell指示要搜索的文件类型。从上面的示例中,我们只想搜索扩展名为.c和.h的文件。
- grep-rnw"我正在寻找的字符串"完成了我需要的。谢谢!
- 不要忘记告诉Linux不要在命令末尾添加"2>/dev/null"来显示不需要的内容。这是唯一一个没有得到大量拒绝权限警告的方法,这些警告只会混淆您正在寻找的结果。
- 注意(特别是新手):上面命令中的引号很重要。
- 谢谢你的回答。不过,如果参数是一个目录,那么唯一真正必要的选择似乎是-r。grep pattern -r path/to/somewhere
- 您也可以添加--colour/--color来突出显示您的搜索项。如grep -rnw --colour . -e"terminal"。
- @D.7你能详细说明它们的重要性吗?
- @sbhatla如果文件名或文件路径包含空格,则引号确保读取文件名,包括/随空格一起读取。
- @eliran malka ren r将正确地遍历目录,但r将遵循符号链接。
- 我喜欢只获取没有结果的文件名,所以我使用grep -rnwl。
- 它是否在目录内的隐藏文件/目录中搜索?
- 您的答案不适用于大量的文件,在AIX中测试了超过15K个文件,但没有起作用。错误-"/usr/bin/grep:0403-027参数列表太长。"
- 在Ubuntu 14.04.3上,这不起作用。我在桑巴安装了目录,它找到了文本。
- 有人能解释为什么在include参数中有一个 include=*.c,h?谢谢
- 我发现-I选项对于"忽略案例"也非常有用。也许把这个放到你的选项列表里。
- -e代表什么?
- 在Solaris 10上不工作
- 这是一个可靠的答案,但问题是,由于-w参数的存在,它只能匹配整个单词。我发现它与任意文本不匹配。
- 我想在这个答案中增加一点,/path/to/somewhere/不能是相对路径。它应该是/directory中的绝对路径。
- 我在函数中使用了您的命令:ing.bashrc findin()grep-rnw"$2"-e"$1"
- --include dir标志引发了一个错误,并且在grep手册页中没有提到(至少在我的CentOS或Debian机器上没有提到)。
- @你说得对,实际上没有--include-dir选项。想知道这是什么时候包括在我的第一个版本中的吗?不记得了。如果能像git一样看到答案更改日志,那就太好了。
- 用s做一些惊人的"忽略错误和警告"的好东西!适合大搜索。
- 或者更简约,grep -r 'rrr' ./。(或如前所述-r而不是-r,以便包含符号链接)
- 我要查找的字符串之一包含特殊字符。您需要添加a-f,以便它计算字符串文本。
您可以使用grep -ilR:
1
| grep -Ril"text-to-find-here" / |
- i代表忽略案例(在您的案例中是可选的)。
- R代表递归。
- l代表"显示文件名,而不是结果本身"。
- /代表从机器的根开始。
- 您认为扫描整个系统平均需要多长时间(显然很大程度上取决于系统)?你认为将正则表达式与grep一起使用会使它更快吗?
- 根据我的经验,-i使它减速很多,所以如果不必要的话不要使用它。在某个目录中进行测试,然后进行概括。几分钟内完成。我认为正则表达式会使它变慢。但是我的意见是基于假设的,我建议你在前面用time来测试它。
- 是的,/*代表这个。不管怎样,我只是测试了一下,发现只有/有效。
- 好的,谢谢。这看起来像是捕获了很多我甚至无法在文本编辑器中打开的文件。它是否可能解释文本中的所有格式,从而随机查找可执行文件中的二进制"noise"结果?
- 你可以加上:2>/dev/null | grep -v"Binary file"。
- 如果不使用regex进行搜索,则可以在大多数系统上使用fgrep代替grep。
- 是的,@markle976,实际上来自man grep:fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings。
- 你的右边,-i减慢速度,至少慢了10倍。
- @wired00当然,对于-i,速度肯定会慢一些,但要知道有多慢是很复杂的:如果使用和不使用测试,可能在运行第二个测试时缓存和使用第一个测试的结果。另外,检查一个长单词(aBcDEFghIj比检查一个短单词(aBc更"昂贵"),因为有更多可能的大小写组合。
- @费多基·阿赫·耶普(Fedorqui-ahh-yep)明白,实际上我一直在使用的是ack 'search text'命令,它非常适合我所需要的,而且速度非常快。它很好,因为它使用了很好的突出显示。
- 您可以用目录grep -Ril"text-to-find-here" ~/sites/的路径替换/或使用。对于当前目录grep -Ril"text-to-find-here" .。
- @在这之后,内森(和超过一百万的浏览量!)我注意到您可以添加参数-i来排除二进制文件。我认为这是关键点,而不是exclude或include。迟到总比不迟到好。
- @费多基,谢谢!我知道,有150万人观看……相当疯狂,对吧?我很感激你两年前给出的答案:)
- @内森非常疯狂!!有趣的是,尽管实际问题是排除二进制文件,但这已成为寻找字符串的标准问题:)
- 恭喜我的@fedorqui+1 100010(这不是二进制btw):-)
- grep -rl 'pattern' .递归也适用于小写的-r。搜索范围点`。`对于当前目录来说,afaik rathan比`/`
- @nitinr708i--r和-r是不同的。从man grep中:递归地读取每个目录下的所有文件。遵循所有链接,不像-r。
- 是否也可以在字符串出现的文件中显示行号?
- @W.M.是的,只要使用-n:grep -n"pattern" file。
- -我非常方便,尤其是在浏览别人编写的代码时。某些语言(如Fortran)在声明函数时不区分大小写:函数/函数伪(X)。
- @费多基:我很惊讶地听到,grep在-i和long words上的速度减慢了,正如我本该想到的那样,boyer-moore"生成的skip-length表驱动"字符串搜索算法在-i上的速度和在longer words上的速度一样快——大概linux grep正在使用更简单的东西!但是en.wikipedia.org/wiki/…说它被使用了!
- @我不知道细节。从常识上讲,寻找"ABC"比"ABC"、"ABC"、"ABC"等更容易,时间安排的例子给了我很大的不同。但我相信你比我更了解它!也许值得问一个问题?
- 如何修改此命令以仅在特定文件类型中查看,例如在.py和.txt文件中?
- @提示参见grep,但仅限于某些文件扩展名
- 谢谢!把它加到你的答案里也许会更好。
- @Fedorqui能给我们举个例子,说明如何只将它应用于特定的文件吗?例如,查找包含"x"文本的filename.txt的所有实例(递归)?谢谢"
- @omega1类似于find -name filename.txt -exec grep 'x' {} \;
- 如何消除警告?我只想要文件名
- @马蒂亚斯看到我刚才的评论。还可以考虑对二进制文件使用-I。
您可以使用ACK。对于源代码来说就像grep。您可以用它扫描整个文件系统。
只做:
在根目录中。
还可以使用正则表达式、指定文件类型等。
更新
我刚刚发现了银搜索器,它类似于ACK,但比它快3-5倍,甚至忽略了.gitignore文件中的模式。
- 非常有用,简单快捷。警告:"在Debian派生的发行版上,ack打包为"ack grep",因为"ack"已经存在(来自beyondgrep.com/install)。你可能会在这些Linux上运行一个汉字代码转换器…
- ACK或ACK GREP有很好的突出显示,但如果使用得当,find+grep在性能上更好。
- 请注意,ripgrep比这里提到的任何东西都要快,包括silver searcher和plain'ol grep。请参阅此博客文章以获取证据。
你可以使用:
1
| grep -r"string to be searched" /path/to/dir |
r代表递归,因此将在指定的路径及其子目录中搜索。这将告诉您文件名以及打印出文件中字符串出现的行。
或类似于您正在尝试的命令(示例:)用于搜索所有javascript文件(*.js):
1
| find . -name '*.js' -exec grep -i 'string to search for' {} \; -print |
这将打印文本出现的文件中的行,但不打印文件名。
除此命令外,我们还可以编写此命令:grep-rn"要搜索的字符串"/路径/到/目录/或/文件-R:递归搜索N:匹配项将显示行号
- 查找版本的thanx。我的grep版本(busybox for nas)没有-r选项,我真的需要另一个解决方案!
- 感谢您提供"查找"版本!能够按".js"或".txt"等进行过滤是非常重要的。没有人愿意花数小时等待grep完成对上一次家庭度假中所有千兆字节视频的搜索,即使命令更易于键入。
您可以使用:
1
| grep -inr"Text" folder/to/be/searched/ |
- 最简单、冗长、递归和不区分大小写。竖起大拇指。
- 如果你加-a3就更好了
- 很酷。
包含给定文本的文件名列表
首先,我相信你用了-H而不是-l。也可以尝试在引号内添加文本,后跟{} \。
1
| find / -type f -exec grep -l"text-to-find-here" {} \; |
例子
假设您正在目录中搜索包含特定文本"apache许可证"的文件。它将显示与下面类似的结果(输出将根据目录内容有所不同)。
1 2 3 4 5 6 7 8
| 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$ |
删除区分大小写
即使不使用"文本"和"文本"这样的大小写,也可以使用-i开关忽略大小写。您可以在此处阅读更多详细信息。
希望这对你有帮助。
- 这就是这个命令的作用:find将把它找到的所有路径传递给命令grep -l"text-to-find-here" "。您可以对文件名添加限制,例如find / -iname"*.txt"仅搜索名称以.txt结尾的文件。
- @辅助-包括一个样本输出,以避免读者混淆。
- @梅恩,这真是一个令人伤心的状况,辅助的评论比你的更有投票权……即使他们的评论是2014年的,而你的评论是2017年的,他们的评论只有6个,而你的评论只有1个(现在是2个),我也不想相信。
- @据说-iname是不区分大小写的,这意味着它还可以找到.txt文件,如txt和txt等。
如果您的grep不支持递归搜索,可以将find和xargs结合起来:
1
| find / -type f | xargs grep 'text-to-find-here' |
我发现这比find -exec的格式更容易记住。
这将输出文件名和匹配行的内容,例如
1
| /home/rob/file:text-to-find-here |
您可能希望添加到grep中的可选标志:
- -i—不区分大小写的搜索
- -l—只输出找到匹配项的文件名
- -h—只输出匹配的行(而不是文件名)
- 这相当于没有文件名的grep 'text-to-find-here',如果find找不到任何文件名。这将挂起并等待用户输入!在xargs中添加--no-run-if-empty作为选项。
- 如果文件名或目录名包含空格(xargs解释为分隔符的字符),find和xargs的组合不会按预期工作。使用find … -exec grep … +。如果您坚持使用find和xargs,请使用-print0和-0。
grep(GNU或BSD)
您可以使用grep工具递归搜索当前文件夹,例如:
注:-r-递归搜索子目录。
您还可以使用globbing语法在特定文件中搜索,例如:
注意:通过使用globbing选项(**),它以特定扩展名或模式递归扫描所有文件。要启用此语法,请运行:shopt -s globstar。您也可以对所有文件(不包括隐藏和不带扩展名的文件)或任何其他模式使用**/*.*。
如果您的错误是您的论点太长,请考虑缩小搜索范围,或者使用find语法,例如:
1
| find . -name"*.php" -execdir grep -nH --color=auto foo {} ';' |
或者使用ripgrep。
ripgrep如果您正在处理较大的项目或大文件,则应使用ripgrep,例如:
在Github项目页面上签出文档、安装步骤或源代码。
它比GNU/BSD grep、ucg、ag、sift、ack、pt或类似工具快得多,因为它建立在Rust的regex引擎之上,该引擎使用有限自动机、simd和积极的文字优化来快速搜索。
它支持在.gitignore文件中指定的忽略模式,因此单个文件路径可以同时与多个glob模式匹配。
您可以使用常用参数,例如:
- -i不敏感搜索。
- -i—忽略二进制文件。
- -w—搜索整个单词(与部分单词匹配相反)。
- -n—显示您的匹配线。
- -C/--context(例如-C5)增加了上下文,因此您可以看到周围的代码。
- --color=auto—标记匹配的文本。
- -H—显示找到文本的文件名。
- -C—显示匹配行的计数。可与-H组合使用。
- 我还发现扩展的全局搜索很有用。但请记住,如果文件数量真的很大,则可能会出现"参数列表太长"错误。(简单的全局化也容易出现这种错误)。
- ReReGRP工具+ 1
- i:忽略模式和输入文件中的大小写区别。
- n:在输出的每一行前面加上输入文件中基于1的行号。
- s:抑制关于不存在或不可读文件的错误消息。
- r:递归读取每个目录下的所有文件。
- 你能解释一下你的答案是如何提高其他答案的,或者它与其他答案有什么区别吗?
- 不需要太复杂的记忆,会覆盖所有模式(case sensictivity->off,包括文件名和行号,并将进行递归搜索等),最后使用"*"将搜索所有目录(不需要指定任何路径或目录名)。
- 对不起,我应该更清楚一点:如果你能把这个解释包括在你的答案中,那就太好了。现在看来,尤其是已经有这么多类似答案的情况下,很难从这样一个简短的答案中看出,比起公认的答案或赞成的答案来,尝试一下会有什么好处。
- 这是好答案+好解释
- @卡彭特,关于这个答案,我最喜欢的一件事就是指出抑制论点,它可以帮助过滤掉噪音,而这对获得我们真正想要的结果并不重要。grep在某些"文件"上打印诸如"函数未实现"、"无效参数"、"资源不可用"等错误。
- @Leetnightshade:我假设你是在向我发表你的评论,因为我要求对稀疏的原始帖子作出解释。请看法比奥的伟大修订,我以前的评论有意义。
- 我很喜欢`-我忽略二进制文件`。
尝试:
1
| 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 ... {} +。
使用pwd从您所在的任何目录中搜索,向下递归
1
| grep -rnw `pwd` -e"pattern" |
更新根据您使用的grep版本,您可以省略pwd。在较新的版本中,如果没有给出目录,那么对于grep来说,.似乎是默认情况。因此:
grep -rnw -e"pattern"
或
grep -rnw"pattern"
会做和上面一样的事!
- 所选答案没有显示默认模式,5个人似乎觉得它有用
- "默认模式"是什么意思?接受的答案包含grep -rnw '/path/to/somewhere/' -e"pattern",这就是您在这里的答案。230万次访问后的5票并不意味着什么。
- 我同意:-)我在原始答案中缺少的是一个用例,您完全不必给出路径,也不必递归地搜索当前目录,而这并没有反映在接受的答案中。因此,深入研究grep是一个很好的学习经验。
- 好的,我明白了。当grep -R"pattern"独立工作时,可以看到grep"pattern"需要检查(dir,文件…)这一点并不容易。那么,在答案中增加一个可能会使更多人受益(最后一篇文章很少被注意到)。但我很高兴你能从中吸取教训:)我有第二个最乐观的答案,而且我看到有很多很多种不同的答案。
- 因此,对于pwd,我试图找到一个简单的黑客,不在完整路径中键入内容,但我确信.和当前目录一样,也足够了,但完全不输入当然是最精简的。
- 实际上,我刚才遇到的问题是,如果没有给出路径,就没有输出。因此,在Fedorqui需要pwd。
- 一旦你掌握了所有这些,就写下grep -rnw 5。在GNU GREP 2.16上这对我很好。
- 这不适用于grep 2.5.1,我目前正在与之合作…
- 使用pwd完全没有必要,因为它是默认的。grep -rnw"pattern"就足够了。
- 事实上,三年前的回答是grep -rnw和类似的,我看不出这个答案是如何增加价值的。
有一个新的实用程序叫silversearcher
1
| sudo apt install silversearcher-ag |
它与Git和其他风投密切合作。所以在.git或其他目录中不会得到任何内容。
你可以简单地使用
它将为你完成任务!
How do I find all files containing specific text on Linux?
(...)
I came across this solution twice:
find / -type f -exec grep -H 'text-to-find-here' {} \;
如果在示例中使用find like,最好将-s(--no-messages)添加到grep中,并在命令末尾添加2>/dev/null,以避免grep和find发出大量拒绝许可的消息:
1
| find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null |
find是在类Unix平台上搜索文件的标准工具(在查找特定文本时与grep结合使用)。顺便说一下,find命令通常与xargs结合在一起。
为了同样的目的存在更快更简单的工具-见下文。当然,如果它们在您的平台上可用,最好尝试一下:
更快更简单的替代方案
Ripgrep-最快的搜索工具:
1
| rg 'text-to-find-here' / -l |
银搜索者:
1
| ag 'text-to-find-here' / -l |
ACK:
1
| ack 'text-to-find-here' / -l |
注意:您也可以将2>/dev/null添加到这些命令中,以隐藏许多错误消息。
警告:除非您真的无法避免,否则不要从"/"(根目录)进行搜索,以避免搜索时间长且效率低!所以在上面的示例中,您最好用子目录名替换"/",例如"/home",这取决于您实际要搜索的位置…
- "find是在类Unix平台上搜索包含特定文本的文件的标准工具"在我看来相当模糊。即使递归grepfind也不会直接在文件内部搜索文本。也许这些额外的工具对一些老的定时器是有用的,而那些非常习惯的人,例如grep根本不会给他们任何时间(我当然不会)。但并没有说它们是无用的。
- "…包含特定文本…":句子的这一部分不准确(因为找不到自己来处理搜索的这一部分)。编辑。谢谢。
- 很高兴能帮上忙!快速浏览一下,唯一的事情就是把文件夹改成目录,但我知道这是我的一次十字军东征,我永远不会赢。尽管如此…
- 为什么不是"目录"而不是"文件夹",但为什么?请分享你的"十字军东征"!
- 我是说用目录代替!参考:你最好用子文件夹名替换"/",这是我的一个宠物皮。esp因为连windows都叫它"目录"。啊..也许你明白了。为什么?因为这就是它的名字。在文件系统级别也叫它。从这个角度来看:它曾经被称为(dos)fol吗?当然不是,它被称为dir(我相信它仍然是)。文件夹是为(我猜)用户友好而精心设计的,但在这种情况下,它可能会降低对不太"高级"用户的友好度?
- 也许它的一部分是语义和学究,但作为一个程序员,他也对语言(不仅仅是计算机语言)很有吸引力……对我来说很重要。函数还引用目录而不是文件夹(不过在Windows中不知道)。
- 同意。完成。(我将删除我的评论,因为它们现在已经过时了)。谢谢你的建议
- 很好。好多了。我也投了赞成票。另一个想法是,如果要找到的regexp/string包含一个-,那么最好先传递给grep --。我也很确定应该引用或转义{},但我可能记错了。另外,我发现您包含了替代工具(不是说我曾经使用过它们,但无论如何我都不需要这个任务的帮助)。当然,根据需要,您也可以将递归与grep一起使用。只是一些额外的想法,不管它们有什么价值。
即使我们不寻找字符串,也可以使用grep。
简单地运行,
将打印出所有文本文件的路径,即只包含可打印字符的文件。
- 我看不出这比使用一个单独的ls或find更好(对于递归)
下面是几个可用于搜索文件的命令列表。
1 2 3 4 5 6 7 8 9 10 11
| 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 |
- 这在现有答案中添加了什么?
- @fedorqui egrep相当于grep -E,意思是--extended-regexp,您可以在这里找到详细信息unix.stackexchange.com/a/17951/19672
银搜索是一个很好的工具,但ripgrep可能更好。
它在Linux、Mac和Windows上工作,几个月前被写在Hacker News上(这有一个到Andrew Gallant的博客的链接,其中有一个Github链接):
Ripgrep–一种新的命令行搜索工具
希望这有帮助…
将grep展开一点,以便在输出中提供更多信息,例如,获取文本所在文件中的行号,方法如下:
1
| find . -type f -name"*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case"searthtext" |
如果您知道什么是文件类型,可以通过指定要搜索的文件类型扩展名来缩小搜索范围,在这种情况下,.pas或.dfm文件:
1
| 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在|管道的另一侧是关键的,将文件名从find传递到嵌入xargs中的grep,允许文件名中带有空格的文件名传递,允许grep将路径和文件名视为一个字符串,而不将其分解到每个空间。
- 你说的不是-name '*.*';它不会在一个名为"file"的文件上拾取,因为模式并不等同于(no.ext);但是*会(好的)。文件除外)。但是还有另一件事:如果你想要所有的文件,为什么要首先指定一个文件名呢?没有其他评论-除了很高兴知道还有人不使用MS术语"文件夹"(说得够多了之后,我不会添加,但我想指出您用文件名所做的稍微不正确的声明-以及"全部"情况下的冗余/无用性)。
一个简单的find可以方便地工作。在您的~/.bashrc文件中命名:
1
| alias ffind find / -type f | xargs grep |
启动新终端并发出:
1
| ffind 'text-to-find-here' |
1
| find /path -type f -exec grep -l"string" {} \; |
注释中的解释
find是一个命令,用于在给定路径的子目录中查找文件和其他对象,如目录和链接。如果不指定文件名应满足的掩码,它将枚举所有目录对象。
1 2
| -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 |
尝试:
1
| find / -type f -exec grep -H 'text-to-find-here' {} \; |
它将搜索所有文件系统,因为/是根文件夹。
用于主文件夹:
1
| find ~/ -type f -exec grep -H 'text-to-find-here' {} \; |
当前文件夹使用:
1
| find ./ -type f -exec grep -H 'text-to-find-here' {} \; |
- 也许文件夹差异的细节对很多人来说是显而易见的……但对新手来说也是非常有用的。+ 1
- 这在现有答案中添加了什么?
- 称之为我的十字军东征,但这个词是"目录"。这不是Windows(它曾经使用'directory'-9x之前)。请停止说"文件夹"。至于你最后的命令,你甚至不需要'/'就仅供参考。
我写了一个类似的python脚本。这就是应该如何使用这个脚本。
1
| ./sniff.py path pattern_to_search [file_pattern] |
第一个参数,path,是我们将递归搜索的目录。第二个参数,pattern_to_search是一个正则表达式,我们希望在一个文件中搜索它。我们使用在python re库中定义的正则表达式格式。在这个脚本中,.还匹配换行符。
第三个论点,file_pattern是可选的。这是另一个对文件名有效的正则表达式。只考虑与此正则表达式匹配的文件。
例如,如果我想搜索扩展名为py的python文件,其中包含Pool(,后跟单词Adaptor,我将执行以下操作:
1 2 3 4 5
| ./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 |
它生成匹配文件的路径和找到匹配的行号。如果找到多个匹配项,则每个行号都将追加到文件名中。
用途:
这将报告当前目录中每个文件中有多少个模式副本。
有一个ack工具可以完全满足您的需求。
http://linux.die.net/man/1/ack
1
| ack -i search_string folder_path/* |
对于区分大小写的搜索,您可以忽略-i。
- 这在现有答案中添加了什么?这是三年多前提出的。
- @Fedorqui 1)没有管道!2)使用正则表达式3)获取行号、具有相对路径的文件名、突出显示的文本等,在搜索后可用于编辑,例如"vim+line no path/file.cpp"将使您直接进入感兴趣的行号。请参见"我的搜索文件夹和子文件夹"下搜索"include"或"hpp"关键字的命令"ack include hpp"的输出。我希望这一点是明确的。以下是示例输出(不能用简单文本显示关键字highlights)process/child.hpp 11:boost/process/child.hpp process/all.hpp 21:include
要搜索字符串并仅使用搜索字符串输出该行,请执行以下操作:
1
| for i in $(find /path/of/target/directory -type f); do grep -i"the string to look for""$i"; done |
例如。:
1 2
| for i in $(find /usr/share/applications -type f); \
do grep -i"web browser""$i"; done |
要显示包含搜索字符串的文件名:
1
| 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; |
例如。:
1 2 3
| for i in $(find /usr/share/applications -type f); \
do if grep -i"web browser""$i"> /dev/null; then echo"$i"; \
fi; done; |
- 与使用find … -exec grep 'str' {} \;相比,我只看到了缺点(如果你必须使用find)。
- 如果find找到的任何文件中包含空格,这将非常糟糕。你可能会以错误的文件和/或完全丢失正确的文件而告终。如果需要使用find,只需使用find ... -exec grep ...。但在这种情况下,一个grep -r ...就足够了。
- 在find to then grep的结果上使用循环有什么意义?这变得不必要的复杂。
grep是你实现这一目标的好朋友。
1
| grep -r <text_fo_find> <directory> |
如果您不关心要查找的文本的大小写,请使用
1
| grep -ir <text_to_find> <directory> |
- 在我的例子中,它看起来像是在任何地方搜索,即使我指定了目录
- @pathros可能与启用递归以及指定的目录有关。换句话说,递归确实以这种方式改变了事情。
- @Pathros哦,如果搜索字符串中有任何-的话,你首先要把--传递给grep,否则会产生有趣的副作用!
试试这个:
1
| find . | xargs grep 'word' -sl |
- 这比grep解决方案慢得多
- @是的,不是直接使用grep,而是将find找到的所有文件传输给运行grep的xargs。我相信你明白这一点,但只是为了增加那些可能不明白的人。这里的命令是……我想不出一个好的类比,但它增加了许多不必要和无害的开销。
您可以使用下面的命令,因为您不需要文件名,但要从所有文件中搜索。以下是我从所有日志文件中捕获"文本"以确保文件名没有打印出来
1
| grep -e TEXT *.log | cut -d' ' --complement -s -f1 |
grep with-e选项与其他选项相比非常快,因为它用于模式匹配
- 就我个人而言,我认为你应该删除#,因为除了那些通常意味着某些事情的评论之外,你不应该是根,除非你必须是根。即使这样,你也不必有提示吗?称之为小气,但多年来我见过很多人只是简单地复制粘贴,做事情却没有真正理解。这里没有说任何遗嘱,但是……只是一个想法。
- 更好的方法使用find+grep stackoverflow.com/a/51023211/7918560
下面的命令对于这种方法很有用:
1
| find ./ -name"file_pattern_name" -exec grep -r"pattern" {} \; |
- 使用find和grep -r有什么意义?它们的含义相同,因此这是多余的。
- 哦!!更正了,事实上,find是为了在筛选的文件上运行grep,而不是所有文件,谢谢。
- 不过,这没有任何意义,您可以使用find进行过滤。
避免麻烦,安装ack grep。它消除了许多许可和报价问题。
1
| apt-get install ack-grep |
然后转到要搜索的目录并运行下面的命令
1 2
| cd /
ack-grep"find my keyword" |
所有以前的答案都建议grep和find。但还有另一种方法:使用午夜指挥官
它是一个免费的实用程序(30年前,通过时间证明),它是可视化的,而不是图形用户界面。有很多函数,查找文件只是其中之一。
我着迷于grep用"rl"做的简单
1 2 3 4
| grep -rl 'pattern_to_find' /path/where/to/find
-r to find recursively file / directory inside directories..
-l to list files matching the 'pattern' |
Use '-r' without 'l' to see the file names followed by text in which the pattern is found!
1
| grep -r 'pattern_to_find' /path/where/to/find |
工作非常完美……
希望它有帮助!
如果有一组文件将始终进行检查,则可以对其路径进行别名,例如:
1
| alias fd='find . -type f -regex".*\.\(inc\|info\|module\|php\|test\|install\|uninstall\)"' |
然后您可以简单地按如下方式筛选列表:
1
| grep -U -l $'\015' $(fd) |
它将fd列表过滤为包含cr模式的文件。
我发现给我感兴趣的文件加别名可以帮助我创建更简单的脚本,然后总是试图记住如何获取所有这些文件。递归的东西也可以工作,但是迟早你将不得不处理掉特定的文件类型。这就是为什么我只找到所有我感兴趣的文件类型。
如果您严格希望使用find,那么:
find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;
find + grep
1.使用find搜索文件,2.然后对所有人执行grep。
可以在一个命令中组合,如下所示:
find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;
这可以使您获得find查找文件的能力。您可以使用它并使用find的不同选项来改进或缩小文件搜索范围。
1
| grep -Erni +"text you wanna search" |
该命令将在当前目录的所有文件和目录中递归搜索并打印结果。
注意:如果grep输出没有着色,可以在shell src文件中使用grep='grep--color=always'别名来更改它。
- 您可能想指出,-i使搜索不区分大小写;默认情况下,它没有这样的功能——也不应该像unix(等)那样是不区分大小写的操作系统。您可能还需要指定其他选项的用途。
试试这个:
1
| find / -type f -name"*" -exec grep -il"String_to_search" {} \; |
或
1
| for i in /*;do grep -Ril"String_to_search" $i;done 2> /dev/null |
- 这在现有答案中添加了什么?
- 好问题-让我们从这个问题的最重要答案开始。我在AIX服务器上尝试了以下命令,日志目录中有超过15K个文件。grep-rnw'/path/to/somewhere/'-e"pattern">>>出现错误"/usr/bin/grep:0403-027参数列表太长。"grep-ril"text to find here"/>>>出现错误"/usr/bin/grep:0403-027参数列表太长。"ack"text to find here'>>>出现错误"segmentation fault(coredump)"。
- find/-type f-name""-exec grep-il"string_to_search";>>>它将生成带有文件名和文件数据的结果。find/-type f-exec grep-h'要在此处查找的文本';>>>它将只生成文件名为的结果。对于i in/;do grep-ril"string_to_search"$i;done 2>/dev/null>>它将像grep-ril"text to find here"/一样工作,但支持大量文件。
- @vipinkumar参数列表太长。是的,这就是xargs的目的。但是,在AIX上不确定它是否有这样的功能;对您的实际命令没有任何评论。
可以使用以下命令从文件中查找特定文本:
1
| cat file | grep 'abc' | cut -d':' -f2 |
- 问题是找到哪些文件包含字符串,而不是在文件中查找字符串。
- 在任何情况下,这都是猫无用的用途…porkmail.org/era/unix/award.html(网址:porkmail.org/era/unix/award.html)
正如彼得在前面的答案中提到的,所有先前的答案都建议grep和find。
但是,自从2001年以来,使用GNOME指挥官和完美的图形用户界面以及大量选项的方法更为复杂,查找文件只是其中之一。它是一个免费的实用程序,并且经过时间证明。
当有许多潜在的匹配项需要筛选时,最好使用带xargs的find。它的运行速度比其他选项要慢,但始终有效。正如一些人所发现的,默认情况下,xargs不处理具有嵌入空间的文件。您可以通过指定-d选项来克服这个问题。
这是@robearl的答案,增强了它,因此它可以处理带有空格的文件:
1 2
| find / -type f | xargs -d '
' grep 'text-to-find-here' |
这是@venkat的答案,同样得到了增强:
1 2
| find . -name"*.txt" | xargs -d '
' grep -i"text_pattern" |
以下是@gert van biljon的答案,同样得到了增强:
1 2
| find . -type f -name"*.*" -print0 | xargs -d '
' --null grep --with-filename --line-number --no-messages --color --ignore-case"searthtext" |
下面是@letalprogrammer的答案,类似地增强了:
1 2
| alias ffind find / -type f | xargs -d '
' grep |
这是@tayab hussain的答案,同样得到了增强:
1 2
| find . | xargs -d '
' grep 'word' -sl |
试试这个
1
| find . -type f -name some_file_name.xml -exec grep -H PUT_YOUR_STRING_HERE {} \; |
- 这并不能回答这个问题。要评论或要求作者澄清,请在他们的帖子下面留下评论。-从审查
- @谢尔盖德尼索夫什么给的?这绝对是一个答案。(它是否有效是另一回事。)
- @那么你应该详细解释一下。
- @谢尔盖德尼索夫。它给出了可能产生正确结果的建议操作过程。或者,即使没有,它也可能帮助其他人。这就是我的意思,"这是一个答案。"如果你想知道它是如何工作的,问问海报。
- @Sireshyarlagadda您应该在回答中提供更多的信息,特别是因为这个命令相对复杂。把它分成若干部分,并解释每一部分。(由于缺乏解释,它被标记为低质量。)
- @jpaugh我确信一行命令/代码对于完整的答案来说是不够的。你可以写一篇评论,给出一个建议的行动方案,但答案应该包括一个解释。这就是为什么这个答案被标记为"低质量帖子"(不是我)。
- 让我们在聊天中继续讨论。
- @我同意你的看法!但我不明白你在评论工具中的"屏蔽"评论是什么意思。
- 这在现有答案中添加了什么?
图形用户界面搜索替代-用于桌面:-因为问题不是在准确地询问命令
searchmonkey:高级文件搜索工具,无需使用正则表达式为系统编制索引。相当于find/grep的图形。可用于Linux(GNOME /KD/Java)和Win(Java)——开源GPLV3
特征:
- advanced regular expressions
- 结果显示在上下文中
- 包含文本的搜索
- panel to display line containing text
- 2018年更新
- 等
下载-链接:
- 主页:http://searchmonkey.embeddediq.com/
- 下载:http://searchmonkey.embeddediq.com/index.php/download latest
- repo:https://sourceforge.net/projects/searchmonkey/files/
.
屏幕截图:
另请参见Platinium Searcher,它类似于Silver Searcher,它是用Go编写的。
例子:
- 欢迎链接到解决方案,但请确保您的答案在没有它的情况下是有用的:在链接周围添加上下文,这样您的其他用户就可以知道它是什么以及为什么存在,然后引用您链接到的页面中最相关的部分,以防目标页面不可用。只不过是链接的答案可能会被删除。