如何在 Linux 上查找所有包含特定文本的文件?

我试图找到一种方法来扫描我的整个 Linux 系统,以查找包含特定文本字符串的所有文件。只是为了澄清,我正在文件中寻找文本,而不是在文件名中寻找文本。

当我查找如何执行此操作时,我两次遇到此解决方案:

find / -type f -exec grep -H 'text-to-find-here' {} \;

但是,它不起作用。似乎显示了系统中的每个文件。

这接近正确的方法吗?如果没有,我应该怎么办?这种在文件中查找文本字符串的功能对于我正在做的某些编程项目非常有用。

答案

请执行下列操作:

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参数排除特定目录。例如,这将排除 dirs 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代表 “显示文件名,而不是结果本身”。
  • /表示从计算机的根目录开始。

您可以使用ack 。就像grep的源代码一样。您可以使用它扫描整个文件系统。

做就是了:

ack 'text-to-find-here'

在您的根目录中。

您还可以使用正则表达式 ,指定文件类型等。


更新

我刚刚发现了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“要搜索的字符串” / path / to / 目录 / 或 / file -r:递归搜索 n:将显示匹配的行号

您可以使用此:

grep -inr "Text" folder/to/be/searched/

包含给定文本的文件名列表

首先,我相信您已经使用-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开关忽略大小写。您可以在此处阅读更多详细信息。

希望这对您有所帮助。

grepGNUBSD

您可以使用grep工具以递归方式搜索当前文件夹,例如:

grep -r "class foo" .

注意: -r递归搜索子目录。

您还可以使用全局语法在特定文件中进行搜索,例如:

grep "class foo" **/*.c

注意:通过使用globlob 选项** ),它将以特定的扩展名或模式递归扫描所有文件。 要启用此语法,请运行: shopt -s globstar您还可以对所有文件(不包括隐藏文件和无扩展名)或任何其他模式使用**/*.*

如果错误指出您的参数过长,请考虑缩小搜索范围,或改用find语法,例如:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

或者使用ripgrep

ripgrep

如果您正在处理较大的项目或大文件,则应改用ripgrep ,例如:

rg "class foo" .

GitHub 项目页面上签出文档,安装步骤或源代码。

它比任何其他工具(例如GNU / BSD grepucgagsiftackpt或类似工具) ucg ,因为它是基于Rust 的 regex 引擎构建的,该引擎使用有限自动机,SIMD 和积极的文字优化来使搜索变得非常快。

它支持.gitignore文件中指定的忽略模式,因此单个文件路径可以同时与多个 glob 模式匹配。


您可以使用常见参数,例如:

  • -i不敏感的搜索。
  • -I忽略二进制文件。
  • -w搜索整个单词(与部分单词匹配相反)。
  • -n显示您的比赛路线。
  • -C / --context (如-C5 ) - 增加背景下,让你看到周围的代码。
  • --color=auto标记匹配的文本。
  • -H显示找到文本的文件名。
  • -c显示匹配行数。可以与-H结合使用。

如果您的grep不支持递归搜索,则可以将findxargs结合使用:

find / -type f | xargs grep 'text-to-find-here'

我发现这比find -exec的格式更容易记住。

这将输出文件名和匹配行的内容,例如

/home/rob/file:text-to-find-here

您可能要添加到grep可选标志:

  • -i不区分大小写的搜索
  • -l仅输出找到匹配项的文件名
  • -h仅输出匹配的行(不输出文件名)
grep -insr "pattern" *
  • i :忽略 PATTERN 和输入文件中的大小写区别。
  • n :输出的每一行都在其输入文件中以从 1 开始的行号作为前缀。
  • s :抑制有关不存在或不可读文件的错误消息。
  • r :递归读取每个目录下的所有文件。

有一个名为The Silversearcher的新实用程序

sudo apt install silversearcher-ag

它与 Git 和其他 VCS 紧密合作。因此,您不会在.git或其他目录中得到任何内容。

您可以简单地使用

ag "Search query"

它将为您完成任务!