Risposte:
Dichiarazione di non responsabilità: questa risposta riguarda specificamente Bash, ma in gran parte si applica alla domanda relativa ai modelli di glob!
Il carattere asterisco ( *
) è un carattere jolly. Ci sono un certo set di caratteri che prenderà il posto e il primo carattere che è un punto ( .
) non è uno di questi. Questo è un caso speciale proprio a causa del funzionamento dei filesystem Unix, i file che iniziano con un punto sono considerati "nascosti". Ciò significa che strumenti come cp
, ls
ecc., Non li "vedranno" a meno che non venga esplicitamente detto di farlo.
Innanzitutto creiamo alcuni dati di esempio.
$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}
Quindi ora abbiamo il seguente:
$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3
Ora giochiamo ad alcuni giochi. È possibile utilizzare il comando echo
per elencare quale sarebbe un determinato carattere jolly ( *
) per un determinato comando in questo modo:
$ 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
È possibile utilizzare il comando shopt -s dotglob
per modificare il comportamento di in *
modo che oltre ai file simili regfile1
corrisponda anche .dotfile1
.
estratto dalla bash
pagina man
dotglob If set, bash includes filenames beginning with a `.' in the results
of pathname expansion.
Esempio:
$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
È possibile ripristinare questo comportamento con questo comando:
$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
Per te stai dicendo cp
che vuoi copiare tutti i file che corrispondono allo schema *
e che non ci sono file.
$ cp foo/.* .
Oppure puoi farlo se vuoi tutto nella foo
cartella:
$ cp foo .
Oppure puoi essere esplicito:
$ cp foot/.* foo/* .
Una forma più compatta che utilizza l'espansione del controvento in bash
:
$ cp foo/{.,}* .
In qualsiasi momento puoi usare il echo
trucco per vedere quali sono i tuoi schemi di file proposti (questo è il termine elegante per cui fa parte la stella).
$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3
Per inciso, se hai intenzione di copiare una directory di file + altre directory, in genere vuoi farlo in modo ricorsivo, questo è il -R
passaggio a cp
:
$ cp -R foo/. .
shopt -s dotglob
, echo *
quindi dare:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
in genere non funzionerà poiché cp
si rifiuterà di copiare foo
su se stesso, probabilmente intendevi cp -R foo/. .
. (nota che cp -R
è quello standard).
zsh
non include .
e ..
nell'espansione di .*
. In zsh
, se uno schema non corrisponde, il comando viene interrotto (di nuovo in modo abbastanza sensato), quindi nel caso generale, cp foo/{,.}* .
fallirà se non ci sono file nascosti o non nascosti.
shopt
non esiste.
Con zsh
, il modo tipico è usare il D
qualificatore glob (per includere i file [D] ot):
cp foo/*(D) .
Nota che con o senza D
, i globs di zsh non includono .
né ..
(come ti aspetteresti).
Se quello che vuoi fare è copiare tutti i file e le directory da una posizione all'altra, puoi usare il rsync
comando standard . Nell'esempio riportato sopra:
mkdir foo && touch foo/.test
rsync -a foo/ .
copierà ricorsivamente tutto il contenuto di foo
, inclusi file nascosti e directory nascoste, nella directory corrente. La barra finale alla fine di foo/
è importante per rsincronizzare; con esso foo
vengono copiati solo i contenuti di , senza che anche rsync copierà foo
. Per esempio:-
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'
Ci sono molte altre opzioni disponibili per modificare rsync, inclusa la copia tra macchine.
dotglob
viene tradottoglobdots
da zsh che non è un nome opzione valido per bash .