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

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

当我正在查找如何做到这一点时,我遇到了这个解决scheme两次:

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

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

这是否接近正确的方式来做到这一点? 如果不是,我该怎么办? 这种在文件中查找文本string的function对于我正在进行的一些编程项目来说是非常有用的。

执行以下操作:

 grep -rnw '/path/to/somewhere/' -e 'pattern' 
  • -r-R是recursion的,
  • -n是行号,
  • -w表示匹配整个单词。
  • -l (小写字母L)可以添加到只给出匹配文件的文件名。

除此之外,– --exclude ,– --include ,– --exclude-dir--include-dir标志可用于高效search:

  • 这将只search那些具有.c或.h扩展名的文件:

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

 grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern" 
  • 就像排除文件一样,可以通过--exclude-dir--include-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代表recursion。
  • l代表“显示文件名,而不是结果本身”。
  • /表示从你机器的根目录开始。

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

做就是了:

 ack 'text-to-find-here' 

在你的根目录下。

您也可以使用正则expression式 ,指定文件types等


UPDATE

我刚刚发现了Silver Searcher ,它比ack快了3-5倍,甚至忽略了.gitignore文件中的模式。

您可以使用:

 grep -r "string to be searched" /path/to/dir 

r代表recursion,因此将search指定的path及其子目录。 这会告诉你文件名以及打印string出现的文件中的行。

或者一个类似于你正在尝试的命令(例如:)在所有JavaScript文件(* .js)中search:

 find . -name '*.js' -exec grep -i 'string to search for' {} \; -print 

这将打印出现文本的文件中的行,但不打印文件名。

你可以使用这个:

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

如果你的grep不支持recursionsearch,你可以把findxargs结合起来:

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

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

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

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

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

  • -i – 不区分大小写的search
  • -l – 只输出find匹配的文件名
  • -h – 只输出匹配的行(不是文件名)

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

首先,我相信你用-H代替-l 。 您也可以尝试添加引号内的文本,然后加上{} \

 find / -type f -exec grep -l "text-to-find-here" {} \; 

假设您正在search包含您的目录中的特定文本“Apache许可证”的文件。 它会显示类似于下面的结果(根据您的目录内容,输出会有所不同)。

 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 -insr "pattern" * 
  • i :忽略PATTERN和input文件中的大小写区别。
  • n :在input文件的前面输出每一行,以1为基准的行号。
  • s :禁止关于不存在或不可读文件的错误消息。
  • r :recursion读取每个目录下的所有文件。

尝试:

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

使用pwd从您所在的任何目录search,向下recursion

 grep -rnw `pwd` -e "pattern" 

更新根据您使用的grep的版本,您可以省略pwd 。 在更新的版本. 似乎是缺省的情况下,如果没有给出目录,则为grep:

grep -rnw -e "pattern"

要么

grep -rnw "pattern"

会做同样的事情,如上所述!

如果您知道源文件的扩展名(并且该项目不太大),请使用:

 grep "class foo" **/*.c 

在您感兴趣的文件夹内。

这里的魔术是在使用扩展通配符( ** ),它可以帮助您以特定的扩展名recursion扫描所有文件。 如果不起作用,请通过shopt -s globstar激活。 您也可以使用**/*.*作为所有文件(不包括隐藏和不带扩展名)。

添加以下有用的参数(对于源代码search最常见):

  • -i – 对于不敏感的search,
  • -w – search单词(与部分单词匹配相反),
  • -n – 显示你的匹配行,
  • --context=5 – 增加上下文,所以你更好地认识周围的代码,
  • -color – 用颜色标记匹配的文本(有时默认是有效的)
  • -I – 忽略二进制文件(通过指定文件扩展名,你实际上)。

如果您的论点太长,请考虑缩小search范围,或者使用find语法。

有一个新的实用工具,称为Silversearcher

 sudo apt install silversearcher-ag 

它与Git和其他VCS密切合作。 所以你不会在.git或其他目录中得到任何东西。

你可以简单地使用

 ag -ia "Search query" 

它会为你做任务!

以下是可用于search文件的几个命令列表。

 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 

即使我们不查找string,也可以使用grep

简单地运行,

 grep -RIl "" . 

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

尝试:

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

这将search所有文件系统,因为/是根文件夹。

对于家庭文件夹使用:

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

对于当前文件夹使用:

 find ./ -type f -exec grep -H 'text-to-find-here' {} \; 
 find /path -type f -exec grep -l "string" {} \; 

来自评论的解释

find是一个命令,用于查找给定path的子目录中的文件和其他对象,如目录和链接。 如果不指定文件名应该符合的掩码,则枚举所有目录对象。

 -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 

希望这是协助…

grep扩展一点,以便在输出中提供更多信息,例如,可以按如下方式获取文本所在文件中的行号:

 find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext" 

如果您知道文件types是什么,则可以通过指定要search的文件types扩展名(在本例中为.pas.dfm文件)缩小search范围:

 find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext" 

选项的简短解释:

  1. . 在当前目录中find指定。
  2. -name*.* ”:对于所有文件(-name“ *.pas ”-o -name“ *.dfm ”):只有*.pas*.dfm文件,或者用-o指定
  3. -type f指定您正在查找文件
  4. -print0--null|的另一边 (pipe道)是至关重要的,将文件名从find发送到xargsembedded的grep ,允许文件名中带有空格的文件名的传递,允许grep将path和文件名视为一个string,而不是打破它在每个空间上。

一个简单的find可以方便地工作。 在你的~/.bashrc文件中~/.bashrc别名:

 alias ffind find / -type f | xargs grep 

开始一个新的terminal,并发出:

 ffind 'text-to-find-here' 

我写了一个类似的Python脚本 。 这是如何使用这个脚本。

 ./sniff.py path pattern_to_search [file_pattern] 

第一个参数path是我们将recursionsearch的目录。 第二个参数pattern_to_search是我们想要在文件中search的正则expression式。 我们使用Python库中定义的正则expression式格式。 在这个脚本中, 也匹配换行符。

第三个参数file_pattern是可选的。 这是另一个正则expression式在文件名上工作。 只有那些匹配这个正则expression式的文件才会被考虑。

例如,如果我想search包含Pool(的扩展名py 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 

瞧,它会生成匹配的文件和行号的匹配path。 如果find多个匹配项,则每个行号都将被附加到文件名。

下面的命令对于这种方法可以正常工作:

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

使用:

 grep -c Your_Pattern * 

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

searchstring并用searchstring输出该行:

 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 

要显示包含searchstring的文件名:

 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; 

银search是一个了不起的工具,但ripgrep可能会更好。

它可以在Linux,Mac和Windows上运行,几个月前写在了Hacker News上 (这里有一个和Andrew Gallant的Blog有链接的链接):

Ripgrep – 一个新的命令行search工具

如果你有一组文件,你会一直检查你可以别名他们的path,例如:

 alias fd='find . -type f -regex ".*\.\(inc\|info\|module\|php\|test\|install\|uninstall\)"' 

那么你可以简单地过滤这样的列表:

 grep -U -l $'\015' $(fd) 

哪个过滤出列表fd到包含CR模式的文件。

我发现别名我感兴趣的文件可以帮助我创build更简单的脚本,然后总是试图记住如何获取所有这些文件。 recursion的东西也适用,但迟早你将不得不面对淘汰特定的文件types。 这就是为什么我只是find所有我感兴趣的文件types开始。

您可以使用下面的命令,因为您不需要文件名,但是要从所有文件中进行search。 这里是我从所有的日志文件捕获“TEXT”,确保文件名不打印:

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

与其他选项相比,使用grep和-e选项相当快,因为​​它是用于PATTERN匹配的。

避免麻烦并安装ack-grep。 它消除了许多许可和报价问题。

 apt-get install ack-grep 

然后转到您要search的目录并运行下面的命令

 cd / ack-grep "find my keyword" 
 grep -Erni + "text you wanna search" 

该命令将在当前目录的所有文件和目录中进行recursionsearch并打印结果。

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

尝试这个:

 find . | xargs grep 'word' -sl 

所有以前的答案build议grep和find。 但还有另一种方法:使用午夜指挥官

这是一个免费的实用程序(30岁,由时间certificate),这是视觉而不是GUI。 有大量的function,查找文件只是其中之一。

有一个确切的工具,可以做你正在寻找的东西。

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

 ack -i search_string folder_path/* 

您可以忽略-i以区分大小写的search