ZSH Globbing 语法解释

ZSH Globbing 语法解释

我想将文件夹dotfiles中的所有内容复制~到 git 存储库来备份它们,并且我正在使用ZSH.

我发现这个命令似乎有效:

cp -a ~/.[^.]* .决赛在哪里。是 git 目录。

我不明白这是如何运作的。谁能给我一个指南,或者告诉我通过谷歌搜索什么来了解更多信息?

我试过ZSH + [^] + globbing

答案1

该语法适用于某些 shell其他甚至zsh在那里,那也是错误的。

.[^.]*匹配以 开头、后跟 0 或多个字符.以外的字符的文件名。.

.这就是您在包含和..的扩展的shell 中需要的语法.*

...是分别用于引用当前目录和父目录的导航工具。它们在 glob 扩展中没有位置,因为 glob 是生成实际文件列表的工具。尽管如此,历史上 shell 一直将它们包含在其全局扩展中,正如 所报道的那样readdir()

zsh,就像 Forsyth shell 及其后代(pdksh、mksh、OpenBSD sh...)或fishshell 已修复该问题,并且从不将.Nor包含..在结果中文件名生成²,即使是像这样的全局变量:

$ echo (.|..)
zsh: no matches found: (.|..)

在一般情况下它也是错误的,因为它会丢失诸如..foobar.

另请注意[^.],虽然许多 shell 支持,但它不是标准 POSIX 语法。

在 POSIXsh语法中,您需要:

cp -a ~/.[!.]* ~/..?* .

(我们添加..?*哪个匹配项,..然后是或更多字符,以涵盖..foobar上述文件名类型)。

zsh(以及上面提到的其他 shell)中,您只需要:

cp -a ~/.* .

希望,最终将被 POSIX 允许/推荐用于 sh我们将会看到更多其他 shell 效仿。


1 根据历史记录,根据传说,名称以.be开头的文件的概念起源于 70 年代该实用程序早期版本中的一个错误ls,该错误最终导致所有以 开头的文件名.被隐藏,而其目的只是隐藏...。当人们开始依赖它来隐藏文件时,这个错误就成为了一个功能

² Bashglobskipdots在 5.2 版本中添加了一个选项。

答案2

让我们把它分成几部分

  • cp -a:将所有内容~/.[^.]*及其下面的目录复制到.
    -a告诉“同时复制子目录并尝试保持文件和目录的所有属性相同”。查看man cp更多信息
  • ~/.[^.]*:您的主目录中的所有隐藏文件和目录,因为:
    • ~是你的主目录
    • *意味着“这可以是任何东西”,因此~/*变为:主目录中的所有文件/目录
    • ~/.*变为:主目录中以点开头的所有文件。乍一看,这与“所有隐藏文件和目录”相同,但事实并非如此,因为您还有目录.(当前目录)和..(父目录)并且您不想要它们
    • [^.]意味着“除了 the 之外的所有可能的字符,因此这解决了and 的.问题”...

因此,该命令总共表示:将主目录中的所有隐藏文件和目录复制到当前目录

相关内容