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

How do I find all files containing specific text on Linux?

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

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

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

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

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


执行以下操作:

1
grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -r-r是递归的,
  • -n为行号,且
  • -w代表匹配整个单词。
  • 可以添加-l(小写L),只需给出匹配文件的文件名即可。

除此之外,还可以使用--exclude--include--exclude-dir标志进行有效搜索:

  • 这将只搜索扩展名为.c或.h的文件:

    1
    grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e"pattern"
  • 这将排除搜索以.o扩展名结尾的所有文件:

    1
    grep --exclude=*.o -rnw '/path/to/somewhere/' -e"pattern"
  • 对于目录,可以通过--exclude-dir参数排除特定目录。例如,这将排除dirs dir1/、dir2/和所有匹配的*.dst/:

    1
    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e"pattern"

这对我来说非常有效,可以达到和你一样的目的。

更多选项请查看man grep


您可以使用grep -ilR

1
grep -Ril"text-to-find-here" /
  • i代表忽略案例(在您的案例中是可选的)。
  • R代表递归。
  • l代表"显示文件名,而不是结果本身"。
  • /代表从机器的根开始。


您可以使用ACK。对于源代码来说就像grep。您可以用它扫描整个文件系统。

只做:

1
ack 'text-to-find-here'

在根目录中。

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

更新

我刚刚发现了银搜索器,它类似于ACK,但比它快3-5倍,甚至忽略了.gitignore文件中的模式。


你可以使用:

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:匹配项将显示行号


您可以使用:

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


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

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

希望这对你有帮助。


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

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(GNU或BSD)

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

1
grep -r"class foo" .

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

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

1
grep"class foo" **/*.c

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

如果您的错误是您的论点太长,请考虑缩小搜索范围,或者使用find语法,例如:

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

或者使用ripgrep

ripgrep

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

1
rg"class foo" .

在Github项目页面上签出文档、安装步骤或源代码。

它比GNU/BSD grepucgagsiftackpt或类似工具快得多,因为它建立在Rust的regex引擎之上,该引擎使用有限自动机、simd和积极的文字优化来快速搜索。

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

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

  • -i不敏感搜索。
  • -i—忽略二进制文件。
  • -w—搜索整个单词(与部分单词匹配相反)。
  • -n—显示您的匹配线。
  • -C/--context(例如-C5)增加了上下文,因此您可以看到周围的代码。
  • --color=auto—标记匹配的文本。
  • -H—显示找到文本的文件名。
  • -C—显示匹配行的计数。可与-H组合使用。


1
grep -insr"pattern" *
  • i:忽略模式和输入文件中的大小写区别。
  • n:在输出的每一行前面加上输入文件中基于1的行号。
  • s:抑制关于不存在或不可读文件的错误消息。
  • r:递归读取每个目录下的所有文件。


尝试:

1
find . -name"*.txt" | xargs grep -i"text_pattern"


使用pwd从您所在的任何目录中搜索,向下递归

1
grep -rnw `pwd` -e"pattern"

更新根据您使用的grep版本,您可以省略pwd。在较新的版本中,如果没有给出目录,那么对于grep来说,.似乎是默认情况。因此:

grep -rnw -e"pattern"

grep -rnw"pattern"

会做和上面一样的事!


有一个新的实用程序叫silversearcher

1
sudo apt install silversearcher-ag

它与Git和其他风投密切合作。所以在.git或其他目录中不会得到任何内容。

你可以简单地使用

1
ag -ia"Search query"

它将为你完成任务!


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,以避免grepfind发出大量拒绝许可的消息:

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",这取决于您实际要搜索的位置…


即使我们不寻找字符串,也可以使用grep

简单地运行,

1
grep -RIl"" .

将打印出所有文本文件的路径,即只包含可打印字符的文件。


下面是几个可用于搜索文件的命令列表。

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


银搜索是一个很好的工具,但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将路径和文件名视为一个字符串,而不将其分解到每个空间。

  • 一个简单的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' {} \;


    我写了一个类似的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

    它生成匹配文件的路径和找到匹配的行号。如果找到多个匹配项,则每个行号都将追加到文件名中。


    用途:

    1
    grep -c Your_Pattern *

    这将报告当前目录中每个文件中有多少个模式副本。


    有一个ack工具可以完全满足您的需求。

    http://linux.die.net/man/1/ack

    1
    ack -i search_string folder_path/*

    对于区分大小写的搜索,您可以忽略-i


    要搜索字符串并仅使用搜索字符串输出该行,请执行以下操作:

    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;


    grep是你实现这一目标的好朋友。

    1
    grep -r <text_fo_find> <directory>

    如果您不关心要查找的文本的大小写,请使用

    1
    grep -ir <text_to_find> <directory>


    试试这个:

    1
    find . | xargs grep 'word' -sl


    您可以使用下面的命令,因为您不需要文件名,但要从所有文件中搜索。以下是我从所有日志文件中捕获"文本"以确保文件名没有打印出来

    1
    grep -e TEXT *.log | cut -d' ' --complement -s -f1

    grep with-e选项与其他选项相比非常快,因为它用于模式匹配


    下面的命令对于这种方法很有用:

    1
    find ./ -name"file_pattern_name"  -exec grep -r"pattern" {} \;


    避免麻烦,安装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' {} \;

    • 如果只想使用grep的某些文件,请使用-name Pattern

      find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

    这可以使您获得find查找文件的能力。您可以使用它并使用find的不同选项来改进或缩小文件搜索范围。


    1
    grep -Erni +"text you wanna search"

    该命令将在当前目录的所有文件和目录中递归搜索并打印结果。

    注意:如果grep输出没有着色,可以在shell src文件中使用grep='grep--color=always'别名来更改它。


    试试这个:

    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


    可以使用以下命令从文件中查找特定文本:

    1
    cat file | grep 'abc' | cut -d':' -f2


    正如彼得在前面的答案中提到的,所有先前的答案都建议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 {} \;


    图形用户界面搜索替代-用于桌面:-因为问题不是在准确地询问命令

    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/

    .

    屏幕截图:

    enter image description here


    另请参见Platinium Searcher,它类似于Silver Searcher,它是用Go编写的。

    例子:

    1
    pt -e 'text to search'