Bash:有没有办法在文件目录中搜索特定的字符串?[重复]


47

可能重复:
在Linux中搜索文本模式

在bash中,我想知道是否有任何命令可以让您知道您要查找的特定字符串是否存在于您当前目录中的文件中。

假设您正在当前目录的一组C文件中寻找函数“ toUpperCase()”。文件很多,所以您不想使用vim手动打开每个文件并检查字符串“ toUpperCase”,因为这会花费很多时间。如果不是bash命令行,是否有另一种方法可以有效地做到这一点?

Answers:


64

grep

grep -R "toUppercase()" *

或者,如果您安装了ack-grep,则只需:

ack-grep "toUppercase"

如果要限制在C文件中的搜索,请使用ack-grep

ack-grep -cc "toUppercase()"

ack-grep也可以安装在OSX上,但是可执行文件名为just ack


如此之多,以至于已经有一个可疑的类似问题;)
David Perry

10

标准的文本搜索工具是grep

要在当前目录的toUpperCase(所有.c文件中查找字符串:

grep -F 'toUpperCase(' *.c

如果还要查看子目录:

grep -r --include='*.c' -F 'toUpperCase('

如果您正在寻找C函数调用,那么ctags可能更合适。您可以在所有源文件上运行一次以创建标识符索引,然后使用编辑器在调用之间导航。所有类似vi的编辑器都可以使用ctags的TAGS文件。如果您使用Emacs,请运行类似的程序etags


ctags对于查找函数定义有用,而不是函数调用
JdeBP

6

您正在使用vim。您已经内置了执行此操作的工具。

可以预见,已经有七个答案要使用grep。但是,到目前为止,我似乎是唯一从您的问题中注意到您正在使用的人vim。因此,尽管你可以使用grep来自内部vim,你可以同时使用vim的内置工具。通过:vimgrep命令调用。

要搜索“当前目录中的所有C源文件以查找对函数的调用toUpperCase()”,请键入以下vim命令

:vimgrep "\<toUpperCase\_s*(" *.c

匹配的结果列表将自动加载到快速修复列表中,可通过以下任一方法进行访问(有关细微差别,请参见在线帮助)

:copen
:cwin

的答案中所述,与or 命令结合使用的是查找函数定义而不是对其进行调用。ctagsGilles:tjump:tselect

为什么要使用:vimgrep

在线帮助(:help grep)引起了很多原因,在这里我不会赘述。除此以外,将的动作:vimgrepdietbuddha的回答进行比较dietbuddha的命令行为grep每个单独的C源文件派生一个单独的进程。它甚至没有使用xargs来减少开销。而且,您仍然必须以某种方式解析输出以在完成后在相关源文件上调用文本编辑器。 :vimgrep根本不会分叉多个其他过程,并且使用结果本身就是简单性。仅选择结果快速修复列表中的一项即可自动将光标定位在相关源文件的相关行上。

实际上,除了自动执行之外,它确实可以完成您手动编写的操作。这是自动执行文本编辑器操作的方式。它会像手动加载一样加载文件,在其中搜索正则表达式(使用您在中的其他位置已使用的正则表达式语法相同vim),记录匹配发生的位置,然后卸载文件。


2

是的,该工具称为grep

grep命令在一个或多个输入文件中搜索包含与指定模式匹配的行。默认情况下,grep打印匹配的行。

基本用法是:

grep something somewhere

或者,更具体地说:

grep [some options] pattern file

在非常简单的情况下,您需要递归地搜索所有文件,因此提供了该-r选项。如果您不关心大写或小写,请使用此-i选项使其不区分大小写。

grep -ri "touppercase()" .

如果只需要匹配的零件,请使用该-o选项。

Grep可以使用正则表达式,并且有大量的手册


2

grep是标准答案-使用-r标志进行递归搜索或结合使用find(此站点上其他问题的讨论和示例,例如this

我最近的首选是ack。它不太可能安装在您的计算机上,但是您可以在Ubuntu上使用apt-get进行安装或直接下载。链接,说明以及比grep更好的原因,请访问http://betterthangrep.com/。


1

findgrep

find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print

为什么不仅如此grep

grep -r string .将遍历当前目录中的所有文件。如果您有目标文件或其他二进制文件,则可能会再次获得二进制结果的匹配项。垃圾 如果子目录中也有fifos或设备文件,则可能会导致未知/意外的后果。

grep string *.c仅搜索当前目录.c文件。

grep string **/*.c 会搜索所有子目录。但是,如果您有大量.c文件,则确实存在超过Shell Glob最大扩展数量的风险。扩展也必须首先发生,这意味着在grep开始之前要遍历完整的树。


0

Grep将解决这个问题,但是一些其他脚本将有助于找到文件的名称和所引用的确切行。如果那是您想要的,我发现以下方法效果很好。我将其保存为Shell脚本,并将其所需的值作为第一个命令行选项传递给它。

for i in $(ls)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?
    if [ $STATUS  -eq 0 ] ; then
        echo $i
        cat $i | grep -n $1
    fi
done

3
grep有一个-H选项,它已经做到了。grep -Hn *
罗伊·里科

每天学习新东西。.感谢@Roy Rico
Tim Brigham

0

我发现没有人回答您的特定问题很有趣:“如何查找当前目录中文件中是否存在特定字符串”。据我所知,没有grep选项只能返回是否在一组文件中找到匹配项。最接近的选项是-l以列出文件名。到目前为止,最接近的答案是蒂姆(Tim),稍作调整:

#!/usr/bin/bash

for i in $(ls *.c 2> /dev/null)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?

    if [ $STATUS  -eq 0 ] ; then
        echo "Found"
        exit
    fi
done

echo "Not found"

您可以通过接受文件扩展名的第二个参数而使此Shell脚本更通用,而不会带来太多麻烦。

道格

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.