Copia solo i file regolari da una directory all'altra


12

Vorrei copiare un contenuto della directory 1 nella directory 2. Tuttavia, mi piacerebbe copiare solo i file (e non le directory) dalla mia directory 1. Come posso farlo?

cp dir1/* dir2/*

quindi ho ancora il problema delle directory.

Inoltre, tutti i miei file non hanno alcuna estensione, quindi . non farà il trucco


1
Non so che estensioni hanno a che fare con esso.
ctrl-alt-delor

1
cp dir1/* dir2oppurecp -t dir2 dir1/*
ctrl-alt-delor

@richard C'è un'abitudine abbastanza comune proveniente dal mondo DOS di non usare estensioni per le directory, che sopravvive ancora in una certa misura, portando alcune persone a supporre che se c'è un punto, allora non è una directory e viceversa.
Gilles 'SO- smetti di essere malvagio' il

ok ma ancora non pertinente.
ctrl-alt-delor,

Risposte:


18
cp dir1/* dir2

cpnon copierà le directory se non esplicitamente detto di farlo ( --recursivead esempio, vedi man cp).

Nota 1: cp molto probabilmente uscirà con uno stato diverso da zero, ma i file saranno comunque stati copiati. Questo può essere un problema quando il concatenamento comandi sulla base di codici di uscita: &&, ||, if cp -r dir1/* dir2; then ..., ecc (grazie a contrebis per il loro commento su tale questione )

Nota 2 : si cpaspetta che l'ultimo parametro sia un singolo nome file o directory. Non ci dovrebbero essere caratteri jolly *dopo il nome della directory di destinazione. dir2\*sarà espanso dalla shell proprio come dir1\*. Cose inaspettate potranno accadere:

  • Se dir2è vuoto e in base alla shell e alle impostazioni:
    • potresti semplicemente ricevere un messaggio di errore, che è lo scenario migliore.
    • dir2/*sarà preso letteralmente (cercando un file / directory chiamato *), che probabilmente porterà anche ad un errore, a meno *che non esista effettivamente.
    • dir2/*verrà rimosso completamente dal comando, lasciando cp dir1/*. Che, a seconda dell'espansione di dir1/*, potrebbe persino distruggere i dati:
      • Se dir1/*corrisponde a un solo file o directory, verrà visualizzato un errore cp.
      • Se dir1/*corrisponde esattamente a due file, uno verrà sovrascritto dall'altro ( Bad ).
      • Se dir/*corrisponde a più file e l'ultima corrispondenza è a, verrà visualizzato un messaggio di errore.
      • Se l'ultima corrispondenza di dir/*è una directory, tutte le altre corrispondenze verranno spostate in essa.
  • Se dir2non è vuoto, dipende di nuovo:
    • Se l'ultima corrispondenza di dir2/*è una directory dir1/*e le altre corrispondenze di dir2/*verranno spostate in.
    • Se l'ultima corrispondenza di dir2/*è un file, probabilmente riceverai un messaggio di errore, a meno che non dir1/* corrisponda a un solo file.

$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).esce con lo stato 1 per me.
contrebis,

1
Sì, esce anche con lo stato 1 anche per me. Ma anche così, cpcopia i file corrispondenti dir1/*su ogni sistema che ho controllato: Arch Linux, Ubuntu 14.04, OpenBSD 3.9 e 5.5, SuSE Linux 8.1, FreeBSD 6.2, Solaris 8, 9 e 10 (dove cpeffettivamente esce con il codice 2). Quindi questo comportamento non è nuovo (SuSE 8.1 è del 2002) né limitato a Linux. cpesce con un codice di uscita diverso da zero perché non può fare tutto ciò che gli è stato detto di fare. Ciò non significa che non faccia nulla .
Adaephon,

3
Certo, ho pensato che valesse la pena notare perché se si concatenano i comandi insieme a &&questo può causare un problema. Stavo provando a qualcosa del genere anche se non riesco a ricordare il contesto ora.
contrebis,

Questo non copia i file nascosti.
felwithe

@felwithe Il fatto che *includa file nascosti o come includere file nascosti dipende dalla shell. Se il *non include file nascosti, puoi abbinarli a .*. Si noti che questo includerà .e ..attivo bashe dashnon attivo zsh. Nel contesto di questa risposta si può ottenere via con cp dir1/* dir1/.* dir2causa .e ..sono le directory e non saranno copiati. zshpuò anche essere fatto per includere file nascosti con *(D).
Adaephon,

7

È la shell che espande i caratteri jolly, non i comandi. Quindi cp dir1/* dir2/*prima espande i due caratteri jolly, quindi chiama cpil risultato. Questo non è affatto quello che apparentemente ti aspetti: a seconda di quanti file ci sono già dir2, dir2/*potrebbe espandersi in uno o più argomenti. Il comando cpnon sa quali dei suoi argomenti derivano dall'espandere il primo modello e quali provengono dall'espandere il secondo modello. Si aspetta che il suo ultimo argomento sia il nome della directory di destinazione. Pertanto, per copiare tutti i file dalla directory dir1nella directory dir2, l'ultimo argomento deve essere la directory dir2:

cp dir1/* dir2

Poiché *corrisponde a tutti i file, cptenta di copiare tutti i file. Questo include le directory: anche le directory sono file. Salta le directory, ma segnala un errore. Copia il contenuto di file speciali come named pipe (è meglio che ci scriva qualcosa, o cplo bloccherà), ecc.

Per copiare solo file regolari , è necessario limitare la corrispondenza. In zsh, puoi usare il qualificatore glob . per quello:

cp dir1/*(.) dir2

Altre shell non hanno questo. È possibile utilizzare il findcomando per filtrare i tipi di file. Supponendo che tu stia eseguendo Linux o Cygwin non embedded:

find dir1 -maxdepth 1 -type f -exec cp -t dir2 {} +

Su Linux, FreeBSD e OSX:

find dir1 -maxdepth 1 -type f | xargs -I {} cp {} dir2

C'è un motivo per specificare -maxdepth 1. Inoltre, esiste un modo per copiare in modo ricorsivo e conservare la gerarchia di directory originale nella directory di destinazione?
Abdull,

@Abdull Senza -maxdepth 1, il findcomando ricorrerebbe in sottodirectory, che qui non era desiderato. Se si desidera copiare l'intero albero di directory incluse le sottodirectory, è una questione del tutto diversa, e la risposta è molto più semplice: cp -a dir1 dir2.
Gilles 'SO- smetti di essere malvagio' il

0

Di seguito è riportato il comando per copiare il file dalla directory di origine a quella di destinazione.

  1. Vai alla cartella di origine quindi scrivi sotto il comando:

    $ cp fileName destination directory path

Esempio:

cp publichOT.sh  /data/home/useradmin
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.