是否存在通过文件扩展名匹配的通配符模式,包括 PWD 和递归?

Is there a globbing pattern to match by file extension, both PWD and recursively?

我需要在所有嵌套目录(包括 PWD)下匹配文件 仅具有一个特定扩展名,BASH 使用“".

来自 ,我相信可能没有办法使用 globbing 来做到这一点。

tl;博士

我需要:

我使用 grep & ls 仅作为示例,但我需要一个也适用于其他命令的 glob 表达式。

例子

假设我有这些文件,都包含“找到我”:

./file1.js
./file2.php
./inc/file3.js
./inc/file4.php
./inc.php/file5.js
./inc.php/file6.php

我需要匹配only/all.php一次:

./file2.php
./inc/file4.php
./inc.php/file6.php

重复 returned:shopt -s globstar; ... **/*.php

这改变了问题;它没有解决它。

重复:ls

输入shopt -s globstar之前...

ls **/*.php returns:

inc/file4.php
inc.php/file5.js
inc.php/file6.php

shopt -s globstar 作为单个命令输入后...

ls **/*.php returns:

file2.php
inc/file4.php
inc.php/file6.php

inc.php:
file5.js
file6.php

重复:grep

输入shopt -s globstar之前...

grep -R "find me" **/*.php returns:

inc/file4.php: find me
inc.php/file6.php: find me

shopt -s globstar 作为单个命令输入后...

grep -R "find me" **/*.php returns:

file2.php: find me
inc/file4.php: find me
inc.php/file5.js: find me
inc.php/file6.php: find me
inc.php/file6.php: find me

当前解决方案:误用&&逻辑

grep -r "find me" *.php && grep -r "find me" */*.php
ls -l *.php && ls -l */*.php

所需的解决方案:通过 globbing 的单个命令

grep -r "find me" [GLOB]
ls -l [GLOB]

来自 grep

的见解

grep 确实有 --include 标志,它实现了相同的结果,但使用了特定于 grep 的标志。 ls 没有 --include 选项。这让我相信没有这样的 glob 表达式,这就是 grep 有这个标志的原因。

使用bash,你可以先做一个shopt -s globstar来启用递归匹配,然后模式**/*.php将扩展到当前目录树中具有.php 扩展。

zsh 和 ksh93 也支持这种语法。其他将 glob 模式作为参数并对其进行自己扩展的命令(如您的 grep --include)可能不会。

建议不同的策略:

使用显式 find 命令在使用 -printf 选项的选定文件上构建 bash 命令。

检查命令的正确性和运行。

1。在所选文件上准备 bash 个命令

 find . -type f -name "*.php" -printf "cp %p ~/destination/ \n"

2。检查输出,正确的命令,正确的过滤器,测试

cp ./file2.php ~/destination/
cp ./inc/file4.php ~/destination/
cp ./inc.php/file5.php ~/destination/

3。执行准备好的 find 输出

 bash <<< $(find . -type f -name "*.php" -printf "cp %f ~/destination/ \n")

使用 shell globing 可以只通过在 glob 的末尾添加 / 来获取目录,但是没有办法专门获取文件(zsh 是一个例外)

插图:

对于给定的树:

file.php
inc.php/include.php
lib/lib.php

假设 shell 支持 non-standard ** glob:

  • **/*.php/ 扩展为 inc.php/

  • **/*.php 扩展为 file.php inc.php inc.php/include.php lib/lib.php

  • 要获得 file.php inc.php/include.php lib/lib.php,您不能 使用 glob。
    => zsh 会是 **/*.php(.)

标准 work-around(任意 shell、任意 OS)

POSIX 递归获取与给定 标准 glob 匹配的文件然后对其应用命令的方法是使用 find -type f -name ... -exec ... :

  • ls -l <all .php files> 将是:
find . -type f -name '*.php' -exec ls -l {} +
  • grep "finde me" <all .php files> 将是:
find . -type f -name '*.php' -exec grep "finde me" {} +
  • cp <all .php files> ~/destination/ 将是:
find . -type f -name '*.php' -type f -exec sh -c 'cp "$@" ~/destination/' _ {} +

备注:这个有点棘手,因为你需要~/destination/之后文件参数,find 的语法不允许 find -exec ... {} ~/destination/ +