如何查找包含特定文本和特定扩展名的文件?

如何查找包含特定文本和特定扩展名的文件?

在 UNIX 中:文件夹中有.sas扩展名为 (programs) 的文件和扩展名为.sas7bdat(tables) 的文件。我需要查找包含文本“liasse”的程序(而不是表格)。我尝试启动以下命令:

grep -rli liasse *.sas ./

在结果中我可以看到一个表名。仅检索程序的命令应该是什么?

答案1

这是一个符合 POSIX 标准的命令,可以grep同时启动多个文件:

find . -type f -name '*.sas' -exec grep -li liasse {} +


您的命令grep -rli liasse *.sas ./没有按预期工作。让我们分析一下发生了什么:

  1. *.sas经历 shell 全局变换。
  2. 如果当前目录中至少有一个对象匹配*.sas,则所有匹配的对象都会被放置在 之后liasse
  3. 如果不存在这样的对象,grep可能会获取文字*.sas作为要检查的路径(这取决于;例如shopt -s nullglobshopt -s failglob调查bash)并抛出警告。
  4. 不管哪种方式,都会在搜索内部文件时递归grep获取并处理它。这将处理程序、表格等下的所有文件。./liasse./

这就是为什么您可以在结果中得到表名。


我的命令仅针对与模式匹配的文件find . -type f -name '*.sas' -exec grep -li liasse {} +运行。重要事项:grep*.sas

  • -type f仅选择常规文件。这样我就可以防止目录名称匹配*.sas(如果有的话)不会被传递给grepgrep没有的话-r无论如何都应该拒绝它们,但这不太优雅)。
  • 引用该模式可防止 shell 进行通配符;find将文字*.sas作为操作数的参数-name;它知道如何解释这样的模式。
  • find … -exec … {} +语法用多个对象代替{}。与 相比,这样grep可以创建更少的进程(可能只有一个) find … -exec … {} \;

答案2

您可以使用find命令按名称递归查找所有文件,然后grep对每个文件运行。最简单的解决方案是-execfind 选项:

find . -name '*.sas' -exec grep -li liasse {} \;

或者,您可以结合find使用xargs

find . -name '*.sas' -print0 | xargs -0 grep -li liasse

这具有稍微好一点的性能,因为它grep针对一大批文件执行,而不是针对每个文件执行。

使用-P选项xargs,您甚至可以并行运行多个 grep 调用。

答案3

这可以通过以下方式实现

find . -type f -name "*.sas" -print0 | "xargs" -0 -e grep -liH -e liasse

如果你没有使用选项xargs的实现-0,即在find和之间传达一组路径xargs,你可以尝试

 find . -type f -name "*.sas" -print | "xargs" -e grep -liH -e liasse

相关内容