在阅读有关 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:~$
在第一种情况下为什么它显示没有这样的目录(*.bash*
)而在下一种情况下它显示文件(.bash*
)
我对这种类型还不熟悉,根据我的自动机理论,类 (*) 表示任意字符串组合,包括 epsilon(empty),那么为什么两种情况下的结果不同......?
答案1
当你这样做时ls *
正在*
被扩展前它被传递给ls
。也就是说,如果我们在目录中有三个文件( a
、b
和)实际上正在运行。c
ls *
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
例外情况是 — 如您已展示的那样 — 当您已明确声明文件将以类似 的模式隐藏时.bash*
。它只是覆盖默认dotglob
设置:
$ shopt -u dotglob # unset dotglob
$ ls .bash*
.bash_aliases .bash_history .bash_logout .bashrc .bashrc.save
无论如何,除了这个怪癖之外,我希望这能帮助你了解表面下发生的事情。
还有其他shopt
标志可以改变通配符的工作方式:、 、 和extglob
。failglob
它们 globstar
和许多其他标志都记录在nocaseglob
nullglob
shopt
Bash 手册。
同样地,模式匹配应该是一些不错的读物。
¹ 除非设置了failglob
或。nullglob