2014-05-16 10 views
43

Sto provando a scrivere uno script Bash che sovrascriverà una directory esistente. Quindi, ho una directory foo/e sto provando a sovrascrivere la barra/con essa. Ma quando lo faccio,Come forzare 'cp' per sovrascrivere la directory invece di crearne un'altra interna?

cp -Rf foo/ bar/ 

ciò che accade è che viene creata una nuova directory bar/foo /. Non lo voglio Ci sono due file in foo/a eb. Ci sono anche file con lo stesso nome in bar /. Voglio che foo/ae foo/b sostituiscano bar/a e bar/b.

risposta

5

Utilizzare questo comando cp:

cp -Rf foo/* bar/ 
+4

Questo non rimuove i file presenti nella barra ma non in pippo. – Ara

+1

Non so cosa intendi con quello. Perché il comando 'cp' dovrebbe rimuovere il file dal sorgente? – anubhava

+0

La mia comprensione era che quando si sovrascrive una directory esistente con un'altra, alla fine la directory sovrascritta dovrebbe essere una copia dell'altro. I.e. alla fine la barra dovrebbe essere una copia di foo, come nel caso della risposta di @ jonathan-wheeler, ma se si ha una barra di file/c e no foo/c, allora bar/c non viene cancellato. In una nota a margine, ho appena notato che non è il caso nemmeno della risposta di Saurabh Meshram. – Ara

19

farlo in due fasi.

rm -r bar/ 
cp -r foo/ bar/ 
+0

Questo pensa che lo volesse in un comando, ma questo sembra ok. –

+7

Questo è in realtà il ** solo ** esempio dato finora che assicurerà che 'bar' sia identico nel contenuto di' foo', non una combinazione di elementi da 'foo' più altri elementi che potrebbero essere già esistiti in' bar '. La risposta altamente motivata di @Saurabh Meshram ha questo problema. – robo

+1

State attenti a questo, perché * rimuoverà * tutti i file dalla barra, anche quelli nascosti. –

52

Si può fare questo -T opzione utilizzando in cp.
Vedere la pagina Man per cp.

-T, --no-target-directory 
    treat DEST as a normal file 

Così come per il vostro esempio che segue è la struttura dei file.

$ tree test 
test 
|-- bar 
| |-- a 
| `-- b 
`-- foo 
    |-- a 
    `-- b 
2 directories, 4 files 

Si può vedere la differenza evidente quando si utilizza -v per verbose.
Quando si utilizza solo l'opzione -R.

$ cp -Rv foo/ bar/ 
`foo/' -> `bar/foo' 
`foo/b' -> `bar/foo/b' 
`foo/a' -> `bar/foo/a' 
$ tree 
|-- bar 
| |-- a 
| |-- b 
| `-- foo 
|  |-- a 
|  `-- b 
`-- foo 
    |-- a 
    `-- b 
3 directories, 6 files 

Quando si utilizza l'opzione -T si sovrascrive il contenuto, trattando la destinazione come un normale file e non directory.

$ cp -TRv foo/ bar/ 
`foo/b' -> `bar/b' 
`foo/a' -> `bar/a' 

$ tree 
|-- bar 
| |-- a 
| `-- b 
`-- foo 
    |-- a 
    `-- b 
2 directories, 4 files 

Questo dovrebbe risolvere il tuo problema.

+9

nel caso in cui qualcuno sia inciampato da questo non funzionerà con OSX cp https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages /man1/cp.1.html – dnfehren

+5

Non è chiaro che questa risposta è ciò che l'OP sta cercando, anche se gli esempi sopra descritti mascherano il problema ... Con l'opzione -T, i file che si trovano in una destinazione esistente ('bar/') ma * not * nella sorgente (' foo/') verrà lasciato in posizione, quindi questo non è ciò che la maggior parte delle persone considererebbe una sovrascrittura completa della directory. ie. se 'bar/baz' esistesse già, sarebbe comunque presente in seguito ... – robo

+0

Non c'è alcuna opzione per pulire la cartella di destinazione nel processo? Non posso crederci! – JohnyTex

3

Il seguente comando assicura dotfile (file nascosti) sono inclusi nella copia:

$ cp -Rf foo/. bar 
+1

È vero? Sembra insolito – Mateng

+2

@Mateng l'ho appena testato - sì è vero. – Matmarbon

1

Molto simile a @ Jonathan Wheeler:

Se non si vuole ricordare, ma non riscrivere bar:

rm -r bar/ 
cp -r foo/ !$ 

!$ visualizza l'ultimo argomento del comando precedente.

+1

Il suggerimento circa! $ È fantastico! –

Problemi correlati