* 在文件搜索中的使用

laz*_*rus 9 filesystem 14.04

在阅读有关 linux 文件搜索的信息时,我得到了以下信息...

要使用 * 通配符搜索文件,请将未知字符串替换为 *,例如,如果您只记得扩展名为 .out,请键入 ls *.out

当我在系统(ubuntu 14.04 LTS)上尝试以下命令时..我得到了

anupam@JAZZ:~$ ls  *.bash* 

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

anupam@JAZZ:~$ ls  .bash*

.bash_history   .bash_logout  .bash_profile  .bashrc

anupam@JAZZ:~$
Run Code Online (Sandbox Code Playgroud)

在第一种情况下为什么它显示没有这样的目录(*.bash*),在下一种情况下它显示文件(.bash*

我是这种风格的新手,根据我的自动机理论,类 (*) 表示包括 epsilon(empty) 在内的任何字符串组合,那么为什么这两种情况下的结果不同......?

Oli*_*Oli 11

当你这样做ls **正在扩大之前将其传递给ls。也就是说如果我们在一个目录中的三个文件(abcls *实际上是运行的ls a b c

当 Bash 无法扩展时,它会通过原始字符串¹。这就是为什么您会在错误中看到通配符以及未找到消息的原因。ls试图显示字面上称为*.bash*.

为什么没有扩大呢?好吧,默认情况下通配符(这个通配符扩展被称为)不会返回隐藏文件。您可以更改此设置shopt -s dotglob(除非您将其粘贴在您的设备中,否则它不会持续存在.bashrc- 默认情况下它可能出于充分的理由被禁用,因此请小心使用它),这是一个快速演示:

$ ls  *.bash*
ls: cannot access *.bash*: No such file or directory
$ shopt -s dotglob
$ ls  *.bash*
.bash_aliases  .bash_history  .bash_logout  .bashrc  .bashrc.save
Run Code Online (Sandbox Code Playgroud)

例外情况是——正如您已经展示的那样——当您已经明确声明文件将使用类似.bash*. 它只是覆盖默认dotglob设置:

$ shopt -u dotglob  # unset dotglob
$ ls .bash*
.bash_aliases  .bash_history  .bash_logout  .bashrc  .bashrc.save
Run Code Online (Sandbox Code Playgroud)

无论如何,除了那个怪癖之外,我希望这可以帮助您了解表面下发生的事情。


还有其他shopt的是如何改变作品的通配符标志:extglobfailglobglobstarnocaseglobnullglob。它们和大量其他shopt标志被记录为Bash 手册的一部分。

同样,关于模式匹配的页面应该是一些很好的阅读。

¹ 除非failglobnullglob已设置。