我想写这样的东西:

$ ls **.py


为了获取所有.py文件名,递归遍历目录层次结构。

即使找到.py文件,外壳程序(bash)也会显示以下输出:

ls: cannot access **.py: No such file or directory


有什么方法可以做我想做的事?

编辑:我想指定我对ls的特定情况不感兴趣,但问题是关于glob语法。

#1 楼

为了在bash中执行递归glob,您需要bash版本4或更高版本的globstar功能。
从bash联机帮助页:
globstar
    If set, the pattern ** used in a pathname expansion context will
    match all files and zero or more directories and subdirectories.
    If the pattern is followed by a /, only directories and
    subdirectories match.

对于您的示例模式:
shopt -s globstar
ls -d -- **/*.py


评论


我建议也启用nullglob

–格伦·杰克曼
2012年10月4日16:50

@glennjackman但是在启用nullglob之前,我强烈建议您阅读以下警告。

– Serge Stroobandt
2013年6月19日在21:53



^警告已移至此处。

–rgajrawala
15年11月29日在7:42

使用bash 3.2,wc -l {** ,.} / *。py可以正常工作

–拉斐尔
18年2月28日在19:50

@Raphael我仔细检查了发行说明,它肯定说它是在4.0中引入的。也许您的发行版已经为此移植了补丁? IIRC RHEL 5已向后移植了一些功能。还值得注意的是,距bash 4发布已经9年了...

–jordanm
18-2-28在20:21



#2 楼

find . -name '*.py'


**除了做一个*以外不做任何其他事情,它们都在当前目录中运行

评论


有趣。虽然,我更专注于glob语法,因为我必须在配置文件(include指令)中使用它。我不需要文件列表。

–保罗
2012年10月4日15:48

@Doug O'Neal,这不再是事实。 bash现在已经复制了zsh功能(尽管它采用的语法接近于ksh93的语法,并且像ksh一样,不支持zsh的globlob限定符,但是限制了其实用性)

–StéphaneChazelas
2012年10月4日20:34

如果您没有bash 4,可以做很多事情。示例:yourcommand`find。 -名称'* .py'`(注意反引号);找 。 -name'* .py'-exec yourcommand {} \;。

–火星
15-10-28在18:43



#3 楼

从Bash 4(还包括zsh)开始,添加了新的globlob选项(globstar),该选项在设置模式时对**的处理方式有所不同。
它与通配符模式匹配,并返回匹配的文件和目录名称,然后通过替换命令中具有匹配项的通配符模式。
通常,当您使用**时,它的工作原理类似于*,但是它递归地递归所有目录(如循环)。
要查看是否启用了该命令,通过shopt globstar进行检查(在脚本中使用shopt -q globstar)。
示例**.py仅适用于当前目录,因为它不会返回可以递归的目录列表,因此这就是为什么您需要使用多个目录的原因级别的通配符**/*.py,因此它可以做得更深。
在此处查看递归查找文件的示例。