通配符`*` 无法匹配某些字符串?

scr*_*apy 7 linux bash

ls  -al  .functions*
-rw-r--r-- 1 root root 471040 Mar  2 10:01 .functions.php.swo
-rw-r--r-- 1 root root 438272 Mar  2 09:57 .functions.php.swp
Run Code Online (Sandbox Code Playgroud)

*可以匹配.php.swo.php.swp
为什么*不能匹配.functions.php

ls  -al  *.swo
ls: cannot access '*.swo': No such file or directory
ls  -al  *swo
ls: cannot access '*swo': No such file or directory
Run Code Online (Sandbox Code Playgroud)

小智 11

作为Shaido 答案的扩展,我想解释一下为什么该-a选项在这里不起作用:

ls命令也没有通配符处理。命令行解释器执行以下步骤:

如果您键入命令行“ mycommand *.c”,命令行解释器将首先用*.c匹配文件列表替换通配符字符串“ ”,然后执行生成的命令行:

mycommand a.c file.c test.c
Run Code Online (Sandbox Code Playgroud)

命令行解释器对所有命令的工作方式相同,因此它无法知道-als命令的情况下意味着“包括隐藏文件” (而-a对于其他命令具有完全不同的含义)...


Sha*_*ido 10

默认情况下,以点开头的文件在文件列表中是隐藏的。匹配这些文件的最简单方法是在表达式的开头放一个点。但是,这将仅匹配以..

ls  -al  .*.swo
Run Code Online (Sandbox Code Playgroud)

另一种方法是dotglob在运行命令之前设置,然后.将包含以开头的文件。

shopt -s dotglob
Run Code Online (Sandbox Code Playgroud)

将其添加到您~/.bashrc的默认设置中。

请注意,设置dotglob可能会导致uninteded结果使用bash shell时,因为两个.(当前目录)和..(父目录),使用时会出现*。使用dotglobset,永远不要尝试使用rm -R *.

  • 警告:dotglob 可能会产生意想不到的后果,因为 `*` 将包含 `.`(当前目录)和 `..`(当前目录的父目录)。尝试设置 dotglob,然后执行 `ls *`。不要*不要*尝试`rm -R *`。 (8认同)
  • 请注意,像`zsh`这样的其他shell实际上以一种既不匹配`.`也不匹配`..`的方式实现了dotglob——在我看来这是一种更有用的行为 (4认同)