Zsh

cp 具有全域模式的隱藏文件

  • July 17, 2019

情況 :

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

我有一個充滿隱藏文件夾和文件的目錄。發生了什麼,解決方案是什麼?

免責聲明:此答案專門針對 Bash,但其中大部分適用於有關 glob 模式的問題!

星號 ( *) 是萬用字元。有一組特定的字元可以代替,第一個字元是點 ( .) 不是其中之一。這是一個特殊情況,只是因為 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您要複製與 pattern 匹配的所有文件*,並且沒有任何文件。

$ cp foo/.* .

或者,如果您想要foo文件夾中的所有內容,也可以這樣做:

$ cp foo .

或者你可以明確:

$ cp foot/.* foo/* .

使用大括號擴展的更緊湊的形式bash

$ cp foo/{.,}* .

在任何時候,您都可以使用這個echo技巧來查看您建議的文件模式(這是星號所屬的花哨術語)。

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

順便說一句,如果您要復製文件目錄+其他目錄,您通常希望遞歸地執行此操作,這就是-R切換到cp

$ cp -R foo/. .

使用zsh,典型的方法是使用D glob 限定符(包括

$$ D $$來自文件):

cp foo/*(D) .

請注意,無論有無D,zsh glob 都不會包含.nor ..(如您所料)。

引用自:https://unix.stackexchange.com/questions/89749