可能重复:
在Linux中搜索文本模式
在bash中,我想知道是否有任何命令可以让您知道您要查找的特定字符串是否存在于您当前目录中的文件中。
假设您正在当前目录的一组C文件中寻找函数“ toUpperCase()”。文件很多,所以您不想使用vim手动打开每个文件并检查字符串“ toUpperCase”,因为这会花费很多时间。如果不是bash命令行,是否有另一种方法可以有效地做到这一点?
可能重复:
在Linux中搜索文本模式
在bash中,我想知道是否有任何命令可以让您知道您要查找的特定字符串是否存在于您当前目录中的文件中。
假设您正在当前目录的一组C文件中寻找函数“ toUpperCase()”。文件很多,所以您不想使用vim手动打开每个文件并检查字符串“ toUpperCase”,因为这会花费很多时间。如果不是bash命令行,是否有另一种方法可以有效地做到这一点?
Answers:
与grep
:
grep -R "toUppercase()" *
或者,如果您安装了ack-grep,则只需:
ack-grep "toUppercase"
如果要限制在C文件中的搜索,请使用ack-grep
:
ack-grep -cc "toUppercase()"
ack-grep
也可以安装在OSX上,但是可执行文件名为just ack
。
可以预见,已经有七个答案要使用grep
。但是,到目前为止,我似乎是唯一从您的问题中注意到您正在使用的人vim
。因此,尽管你可以使用grep
来自内部vim
,你可以同时使用vim
的内置工具。通过:vimgrep
命令调用。
要搜索“当前目录中的所有C源文件以查找对函数的调用toUpperCase()
”,请键入以下vim
命令
:vimgrep "\<toUpperCase\_s*(" *.c
匹配的结果列表将自动加载到快速修复列表中,可通过以下任一方法进行访问(有关细微差别,请参见在线帮助)
:copen
:cwin
如的答案中所述,与or 命令结合使用的是查找函数定义而不是对其进行调用。ctags
Gilles
:tjump
:tselect
:vimgrep
?在线帮助(:help grep
)引起了很多原因,在这里我不会赘述。除此以外,将的动作:vimgrep
与dietbuddha
的回答进行比较。 dietbuddha
的命令行为grep
每个单独的C源文件派生一个单独的进程。它甚至没有使用xargs
来减少开销。而且,您仍然必须以某种方式解析输出以在完成后在相关源文件上调用文本编辑器。 :vimgrep
根本不会分叉多个其他过程,并且使用结果本身就是简单性。仅选择结果快速修复列表中的一项即可自动将光标定位在相关源文件的相关行上。
实际上,除了自动执行之外,它确实可以完成您手动编写的操作。这是自动执行文本编辑器操作的方式。它会像手动加载一样加载文件,在其中搜索正则表达式(使用与您在中的其他位置已使用的正则表达式语法相同vim
),记录匹配发生的位置,然后卸载文件。
grep
是标准答案-使用-r标志进行递归搜索或结合使用find
(此站点上其他问题的讨论和示例,例如this)
我最近的首选是ack
。它不太可能安装在您的计算机上,但是您可以在Ubuntu上使用apt-get进行安装或直接下载。链接,说明以及比grep更好的原因,请访问http://betterthangrep.com/。
find
和 grep
find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print
为什么不仅如此grep
?
grep -r string .
将遍历当前目录中的所有文件。如果您有目标文件或其他二进制文件,则可能会再次获得二进制结果的匹配项。垃圾 如果子目录中也有fifos或设备文件,则可能会导致未知/意外的后果。
grep string *.c
仅搜索当前目录.c
文件。
grep string **/*.c
会搜索所有子目录。但是,如果您有大量.c
文件,则确实存在超过Shell Glob最大扩展数量的风险。扩展也必须首先发生,这意味着在grep
开始之前要遍历完整的树。
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
我发现没有人回答您的特定问题很有趣:“如何查找当前目录中文件中是否存在特定字符串”。据我所知,没有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脚本更通用,而不会带来太多麻烦。
道格