cp 带有 glob 模式的隐藏文件

cp 带有 glob 模式的隐藏文件

情况 :

$ mkdir foo && touch foo/.test
$ cp foo/* .
zsh: no matches found: foo/*
(or bash : cp: cannot stat ‘foo/*’: No such file or directory)

我有一个充满隐藏文件夹和文件的目录。发生了什么以及解决方案是什么?

答案1

对于zsh,典型的方法是使用D 全局限定符(包括 [D]ot 文件):

cp foo/*(D) .

请注意,无论有没有D,zsh glob 都不会包含.nor ..(如您所料)。

答案2

免责声明:这个答案专门针对 Bash,但其中大部分适用于有关全局模式的问题!

星号 ( *) 是通配符。它将取代某些特定的字符集,并且第一个字符是点 ( .) 不是其中之一。这是一个特殊情况,只是因为 Unix 文件系统的工作方式,以点开头的文件被视为“隐藏”。这意味着诸如 、 等工具cp不会ls“看到”它们,除非明确告知这样做。

例子

首先让我们创建一些示例数据。

$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}

所以现在我们有以下内容:

$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3

现在让我们玩一些游戏。您可以使用该命令echo列出*给定命令的特定通配符 ( ),如下所示:

$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3


$ echo reg*
regdir1 regdir2 regfile1 regfile2 regfile3

$ echo .*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2

$ echo .* *
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3

$ echo .dotdir*
.dotdir1 .dotdir2

改变行为?

您可以使用该命令shopt -s dotglob更改 的行为,*以便除了类似的文件之外,regfile1它也会匹配.dotfile1.

bash手册页摘录

dotglob If set, bash includes filenames beginning with a `.' in the results 
        of pathname expansion.

例子:

$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3

您可以使用以下命令恢复此行为:

$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3

你的情况?

对于您来说,您告诉cp您要复制与模式匹配的所有文件*,但没有任何文件。

$ cp foo/.* .

或者,如果您想要文件夹中的所有内容,您可以这样做foo

$ cp foo .

或者你可以明确地说:

$ cp foot/.* foo/* .

使用大括号扩展的更紧凑形式bash

$ cp foo/{.,}* .

您可以随时使用该echo技巧来查看您建议的文件模式(这是星号所属部分的奇特术语)。

$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3

顺便说一句,如果您要复制文件目录+其他目录,您通常希望递归地执行此操作,即切换-Rcp

$ cp -R foo/. .

答案3

shell 在解析字符时将这些文件视为隐藏文件*,因此cp不会接收任何这些文件名作为参数。

您可以通过显式指定来复制它们cp foo/.* .

答案4

如果您想要做的是将所有文件和目录从一个地方复制到另一个地方,您可以使用标准rsync命令。在您上面给出的示例中:

mkdir foo && touch foo/.test
rsync -a foo/ .

将递归地将 的所有内容foo(包括隐藏文件和隐藏目录)复制到当前目录中。末尾的斜杠foo/对于 rsync 很重要;使用它只会foo复制的内容,没有它 rsync 也会复制foo。例如:-

mkdir src && mkdir dest && touch src/.test
rsync -a src  dest    // copies 'src' contents to 'dest/src'
rsync -a src/ dest    // copies 'src' contents to 'dest' 

还有许多其他选项可以调整 rsync,包括在机器之间复制。

相关内容