我想将文件夹dotfiles
中的所有内容复制~
到 git 存储库来备份它们,并且我正在使用ZSH
.
我发现这个命令似乎有效:
cp -a ~/.[^.]* .
决赛在哪里。是 git 目录。
我不明白这是如何运作的。谁能给我一个指南,或者告诉我通过谷歌搜索什么来了解更多信息?
我试过ZSH
+
[^]
+
globbing
答案1
该语法适用于某些 shell其他甚至zsh
在那里,那也是错误的。
.[^.]*
匹配以 开头、后跟 0 或多个字符.
以外的字符的文件名。.
.
这就是您在包含和..
的扩展的shell 中需要的语法.*
。
.
和..
是分别用于引用当前目录和父目录的导航工具。它们在 glob 扩展中没有位置,因为 glob 是生成实际文件列表的工具。尽管如此,历史上 shell 一直将它们包含在其全局扩展中,正如 所报道的那样readdir()
。
zsh
,就像 Forsyth shell 及其后代(pdksh、mksh、OpenBSD sh...)或fish
shell 已修复该问题,并且从不将.
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 的.
问题”.
..
因此,该命令总共表示:将主目录中的所有隐藏文件和目录复制到当前目录