Copia il contenuto della directory usando il comando 'cp'


33

Come copi tutto il contenuto di una directory in un'altra?

Per esempio:

$ cd /home/newuser
$ cp -a /backup/olduser/* .

Il problema con quanto sopra è che il modello globale '*' corrisponde alle directory nascoste '.' e '..' e si finisce con una directory 'olduser' all'interno di 'newuser', così come i contenuti.

Potresti anche fare qualcosa del genere:

$ rmdir /home/newuser
$ cp -a /backup/olduser /home/newuser

Ma cosa succede se newuser contiene già alcuni file e directory predefiniti?

Qual è il modo più semplice, più corretto, più semplice da ricordare e non disordinato per spostare il contenuto di una directory in un'altra usando solo il comando base 'cp' e la shell?

Risposte:


31

Provare:

cp -ra /backup/olduser/. /home/newuser

È fantastico, ma non riesco a capire esattamente come funzioni. Penso che sia probabilmente perché non capisco come .e come ..funzioni. Ti interessa spiegare?
bradley.ayers,

Questo ha funzionato per me ma cp -r ./a bnon l'ha fatto. Qualche idea sul perché?
Brig

3
funziona anche per me, ma l' ropzione non è necessaria. L' aopzione implica r.
MountainX

1
il parametro -r sembra essere un po 'ridondante a questo punto!
Master of Celebration,

Il -aparametro non fa nulla per aiutare in questa situazione. Il comando cp -r ./a/. bcopierà il contenuto e solo i contenuti della directory anella directory b. La -abandiera conserva collegamenti, timestamp ecc., Che non è rilevante per la domanda.
Steen Schütt,

23

Due directory a e b.

Entrambi hanno file in.

Sei in una directory che contiene a e b.

cp -r ./a b

-r = ricorsivamente.


Non vuoi -a per ottenere tutti i file?
bw

7
L'argomento -a non ha nulla a che fare con tutti i file, è l'abbreviazione di archivio, manterrà la proprietà dei file, i permessi, i tempi di accesso ecc. L'argomento -a (sebbene molto utile) non è un'opzione standard, e diverse implementazioni cp don non fornirlo.
theotherreceive del

1
@mch: incluso automaticamente, perché hai detto cpdi copiare una directory aed a/.somedotfileè contenuto da a. se besiste, questo comando creerà una copia esatta di aat b/a.
Quack Quixote

2
Modo semplice:cp -R /some/dir/* /another/dir
n0pe

1
Questo copia a / foo in b / a / foo invece che in b / foo
Sparr

19

Ricordare che, per impostazione predefinita, cpcopia la prima directory nella seconda directory se esiste la seconda.

Ad esempio cp -r a bcopierà la directory a in b. Se bnon esiste, verrà creato con il contenuto di a.

Se si desidera copiare il contenuto di ain b(ad esempio quando si copia un intero file system in un punto di montaggio) utilizzare:

cp -r a/. b

come nella risposta precedente.

Si noti inoltre che -a, utilizzato in alcune delle altre risposte, è uguale -dr --preserve=alle conserverà timestamp, contesto e attributi estesi.


Come /.funziona
Bradley.ayers,

a/.rappresenta il contenuto della directory 'a' in contrapposizione alla directory stessa, nella maggior parte delle situazioni è sinonimo ma quando viene utilizzato cp -r, evita il comportamento predefinito di cp (copiando un INTO b).
Nicolas Bonnefon,

suggerimento fantastico, questo è esattamente quello che stavo cercando ma non sono riuscito a trovare altrove - tutto quel 'foo / *' o '-r foo /' che fallisce in casi angolari.
Tener,

@TimoHuovinen '.' non è affatto un jolly. È letteralmente la directory "parent", e ".." è il nonno. Ciò significa "/foo/./././././." è la stessa directory di '/ foo' e '/ foo / bar / ..' è la stessa directory di '/ foo'. Pensa a loro come hardlink integrati nel filesystem.
Quuxman,

@quuxman grazie, non ero a conoscenza di allora. Rimuoverò il mio vecchio commento per evitare di confondere le persone.
Timo Huovinen,

6

A meno che tu non abbia riconfigurato seriamente la tua shell, il modello globbing '*' non corrisponde '.' o '..', come puoi verificare usando solo echo *. Quello che fa invece è omettere i file il cui nome inizia con un '.', Quindi il tuo approccio mancherà tutti i file nascosti. Puoi modificare alcuni di questi comportamenti con le opzioni della shell, ad esempio l'opzione dotglob in bash, ma non sarà l'opzione portatile e robusta che stai cercando.

Se è necessario farlo più di una o due volte, si consiglia di esaminare rsync o all'unisono (a seconda delle esigenze specifiche) con specifiche di origine e destinazione accuratamente predisposte.

Un'altra alternativa è quella di mettere la directory di origine in un tarball e decomprimerla sulla directory di destinazione esistente.


1
io uso questo: ( cd /src/dir ; tar cf - . ) | ( cd /dest/dir ; tar xf - )... il tar cf - .tar è la directory dei sorgenti, inclusi i file dot e lo sputa a STDOUT, che viene reindirizzato allo STDIN di tar xf -.
Quack Quixote

Penso che il punto centrale dell'OP sia come fare riferimento ai file che iniziano con '.' ma non lo speciale "." e '..' directory. C'è una soluzione molto più elegante sopra invece di usare rsync o qualche altro programma complesso.
Quuxman,

2

Questo copierà sia i file normali che quelli nascosti, escludendo la directory principale ( ..):

cd /directory/to/copy
cp -r * .[^.]* /destination/directory

Se non si esclude la directory principale, si finisce con tutto il contenuto della ..directory di destinazione.


1
Ma questo esclude ancora i nomi che iniziano con .. (ad esempio, ...o ..super-hidden).
Scott,

0

Per copiare i file che iniziano con un punto, fai semplicemente cp. * Target /

Il modo più semplice è semplicemente fare il comando cp due volte.

Come dice Peter Eisentraut, le normali regole del globbing non includono ... e. (hm, come terminare questa frase?;)

Usa -r per renderlo ricorsivo e -i per fare in modo che cp ti chieda se vuoi davvero sovrascrivere un file.

cp -ri /backup/olduser/* /newuser/
cp -ri /backup/olduser/.* /newuser/

Di solito *non corrisponde .o .., ma lo fa se si utilizza .*. Prova echo .*. È possibile escludere .e ..con il seguente schema: .[^.]*.
MCH

@mch: ma .[^.]*esclude comunque i nomi che iniziano con .. (es. ...o ..super-hidden).
Scott,

0

Questo funziona per copiare tutti i file e le directory tranne le directory nascoste ricorsivamente dalla directory corrente ovunque:

cp -rf * ^.* 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.