Bash 递归命令(**/*)也包含当前目录文件的文件

Bash 递归命令(**/*)也包含当前目录文件的文件

免责声明:我刚刚从 Microsoft Windows 移植到 Linux,我的知识主要来自不同的 Linux 论坛。

我尝试使用“**/*”命令向我的 mp3 播放器提供如下所示的文件列表。

mpg123 **/*.mp3

上述命令运行良好,但忽略了当前目录的文件,即它从子目录中获取文件,但不从当前目录中获取文件。

我也在 ls 命令上尝试了同样的事情,但结果相同(忽略当前目录文件)。

ls **/*

是否有任何变化,以便我也可以包含当前目录文件。

注意:我从以下位置获取此命令Stack Overflow 上的这篇文章但由于声誉较低,无法询问作者。

答案1

正如steeldriver所说globstar,如果您希望 Bash 以递归方式处理,则需要启用shell 选项**。默认情况下,它是关闭的。也就是说,在 Bash 中,默认情况下,**其行为与 相同*,这就是您所看到的行为。

  • shopt globstar告诉您它是打开还是关闭。
  • shopt -s globstar将其打开(-s表示“设置”)。
  • shopt -u globstar将其关闭(-u“未设置”)。

help shopt给出shopt内置命令的详细信息。

Bash 参考手册解释***

*

匹配任何字符串,包括空字符串。当globstar 启用 shell 选项,并且*在文件名扩展上下文中使用 ' ' 时,*用作单个模式的两个相邻 ' ' 将匹配所有文件以及零个或多个目录和子目录。如果后面跟着 ' /',则两个相邻 ' *' 将仅匹配目录和子目录。

globstar**火柴零个或多个目录,允许**/*.mp3匹配*.mp3当前目录中的文件,以及当前目录的子目录中的文件,以及那些目录等等。也就是说,**/*.mp3匹配的文件与您编写的相同:

*.mp3 */*.mp3 */*/*.mp3 */*/*/*.mp3 ...

(其中,代替...,序列继续深入到递归目录树所需的深度;另请参阅FedonKadifeli 的评论,其中呈现了前两个术语)。

没有globstar**与 的效果相同*。则**/*.mp3相当于*/*.mp3,即它匹配*.mp3当前目录子目录中的文件,但不匹配子目录中的文件,也不匹配这些子目录的任何更深的后代中的文件,也不在当前目录本身

请注意,默认情况下,globstar不会递归到隐藏目录(即名称以..开头的目录*(和)与路径组件开头的?a 不匹配;同样,与它将扩展到的任何路径组件开头的a 不匹配。要更改此设置(这会更改和),您可以打开shell 选项。但您很可能不希望这样。.**.***dotglob


对 shell 选项的更改将应用​​于 shell 的单个运行实例,只要该实例正在运行(或直到您再次更改选项)。因此,globstar在一个 Bash shell 中打开不会影响将来的 Bash shell,也不会影响同时运行的其他 Bash shell。

但是,如果您希望更改持续时间更短,您可以使用括号创建子shell在其中设置它并运行您的命令:

(shopt -s globstar; mpg123 **/*.mp3)

或者也许您globstar从现在起确实希望在所有交互式 Bash shell 中启用此功能。如果是这样,您可以shopt -s globstar在文件末尾单独一行放置~/.bashrc,。

相关内容