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

Ash*_*ish 6 bash files

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

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

mpg123 **/*.mp3
Run Code Online (Sandbox Code Playgroud)

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

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

ls **/*
Run Code Online (Sandbox Code Playgroud)

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

注意:我从Stack Overflow 上的这篇文章中得到了这个命令,但由于声誉较低,无法询问作者。

Eli*_*gan 7

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

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

help shopt提供有关shopt内置的​​详细信息。

\n

Bash参考手册解释***

\n
\n

*

\n

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

\n
\n

使用globstar,**匹配零个或多个目录,这允许**/*.mp3匹配*.mp3当前目录中的文件、当前目录的子目录中的文件、这些目录的子目录中的文件等等。这就是说**/*.mp3匹配与您编写的相同的文件:

\n
*.mp3 */*.mp3 */*/*.mp3 */*/*/*.mp3 ...\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

没有globstar**只是具有相同的效果*。then**/*.mp3相当于*/*.mp3,即,它匹配*.mp3当前目录的子目录中的文件,但不匹配子目录中的文件,也不匹配这些子目录的任何更深层次的子目录中的文件,也不匹配当前目录本身中的文件

\n

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

\n
\n

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

\n

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

\n
*.mp3 */*.mp3 */*/*.mp3 */*/*/*.mp3 ...\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n