Qual è il modo più veloce per spostare un milione di immagini da una directory all'altra in Linux?


14

Ho un milione di immagini che occupano 30 GB di spazio su disco che devono essere spostate da una directory locale a un'altra directory locale.

Quale sarebbe il modo più efficace per farlo? Usando mv? Usando cp? Usando rsync? Qualcos'altro?

Devo prendere questi:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

e spostali qui:

/path/to/new/img/dir/

5
Non penso che tu possa battere mv, dal punto di vista delle prestazioni, se entrambe le directory sorgente e destinazione risiedono nello stesso filesystem.
Frédéric Hamidi,

Risposte:


26

rsync sarebbe una scelta sbagliata perché fa un sacco di lavoro in background client / server che tiene conto di sistemi locali e remoti.

mvè probabilmente la scelta migliore. Se possibile, dovresti provare mv directory_old directory_newpiuttosto che mv directory_old/* directory_new/. In questo modo, muovi una cosa invece di un milione di cose.


6
+1 per il consiglio di spostare le directory anziché i file.
Ex Umbris,

4
Inoltre, l'espansione dei caratteri jolly probabilmente spezzerebbe gli argomenti massimi supportati mvse parliamo di milioni.
slhck,

6
rsync gestisce bene i trasferimenti su supporti di archiviazione locali. Forza cose come - whole-file (rimuovendo l'implementazione dell'algoritmo delta xfer) e impedisce altre cose come --compression che non ha alcuno scopo nei trasferimenti locali. Se le directory risiedono su diversi filesystem, 'mv' non fornirà alcun tipo di prestazione. Se risiedono sullo stesso filesystem, allora semplicemente "mv" hanno detto le directory come queste persone.
UtahJarhead,

Se ci sono molte immagini, l'uso di un semplice jolly di shell supererà la riga di comando massima.
Raúl Salinas-Monteagudo,

1
Lo spostamento tra i dischi sposta comunque tutti i dati. Sullo stesso disco, mvaggiorna solo le informazioni sull'inode, quindi mv directory_old directory_newfunziona più velocemente dimv directory_old/* directory_new
Anshul

14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Ciò non sovraccaricherà l'espansione dell'argomento.
  • È possibile specificare l'estensione del file, se lo si desidera. (-nome ...)
  • find -print0con xargs -0consente di utilizzare spazi nei nomi.
  • xargs -rnon funzionerà a mvmeno che non ci sia qualcosa da spostare. ( mvsi lamenterà se non viene fornito alcun file sorgente).
  • La sintassi mv -tconsente di specificare prima la destinazione e poi i file di origine, necessari per xargs.
  • Lo spostamento dell'intera directory è ovviamente molto più veloce, poiché avviene in tempo costante indipendentemente dal numero di file in essa contenuti, ma:
    • la directory di origine scomparirà per una frazione di tempo e potrebbe creare problemi;
    • se il processo utilizza la directory corrente come directory di output (al contrario di fare sempre riferimento a un percorso completo da una posizione non mobile), è necessario riavviarlo. (come fai con la rotazione del registro ).

A proposito, mi chiedo se devo davvero spostare una così grande quantità di file contemporaneamente. L'elaborazione in batch è sopravvalutata. Cerco di non accumulare enormi quantità di lavoro se riesco a elaborare le cose nel momento in cui vengono generate.


Funziona abbastanza bene per spostare file attraverso filesystem sullo stesso server. Abbastanza bene che non mi sono preoccupato di cercare una soluzione in rsync. Certo ci sono voluti un'ora o due, ma funziona. Una cosa da notare, se si trova trova un nome di directory anziché "." - assicurati di usare la barra finale nel comando find, altrimenti la directory verrà ricreata nella destinazione del comando mv.
Speeddymon,

7

Se le due directory si trovano sullo stesso filesystem, utilizzare mvsu DIRECTORY e non il contenuto della directory.

Se risiedono su due diversi filesystem, utilizzare rsync:

rsync -av /source/directory/ /destination

Notare il finale /sulla fonte. Ciò significa che copierà il CONTENUTO della directory e non la directory stessa. Se lo lasci /spento, i file verranno comunque copiati ma si troveranno in una directory denominata /destination/directory. Con /, i file saranno appena dentro/destination

rsyncmanterrà la proprietà del file se lo esegui come root o se i file sono di tua proprietà. Manterrà anche il mtimefile di ogni singolo file.


2
Per copiare una cartella di grandi dimensioni da un disco rigido a un altro disco rigido, rsyncsembra che cerchi in giro mv. Grazie per il consiglio!
leo-the-manic

2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

Quando usi 'cp' ogni file fa un open-read-close-open-write-close. Tar utilizza diversi processi per la lettura e la scrittura e più battistrada per operare su più file contemporaneamente. Anche su un singolo box CPU le app multithread sono più veloci.


2
Sebbene ciò possa rispondere alla domanda, sarebbe una risposta migliore se tu potessi fornire qualche spiegazione sul perché lo faccia.
DavidPostill

1
Se si trovano nel computer locale, è probabile che risiedano nello stesso filesystem. Usando tar c | tar xottieni un costo di O (total_size) invece di O (file_count).
Raúl Salinas-Monteagudo,

1

Poiché sia ​​directory_old che directory_new si trovano sullo stesso filesystem, è possibile utilizzare cp -linvece che mvcome opzione. cp -lcreerà un collegamento reale ai file originali. Quando hai finito con 'sposta' e sei soddisfatto del risultato, puoi rimuovere questi file da directory_old. in termini di velocità sarà lo stesso di "mv" quando crei prima i collegamenti e poi rimuovi quelli originali. Ma questo approccio ti consente di iniziare dall'inizio se questo ha senso


0

Dipende (tm). Se il tuo filesystem è copy-on-write, allora copy ( cpo rsync, per esempio) dovrebbe essere paragonabile a una mossa. Ma per i casi più comuni, move ( mv) sarà il più veloce, dal momento che può semplicemente cambiare le parti di dati che descrivono la posizione di un file (nota: questo è eccessivamente semplificato).

Quindi, nella tua installazione media di Linux, ci proverei mv.

EDIT: @ Frédéric Hamidi ha un buon punto nei commenti: questo è valido solo se si trovano entrambi sullo stesso filesystem e sullo stesso disco. Altrimenti i dati verranno comunque copiati.


0

Per copiare almeno ~ 10k di file (nessuna directory), cp si è lamentato di:

impossibile eseguire / bin / cp: elenco degli argomenti troppo lungo

L'opzione migliore è Rsync:

destinazione sorgente rsync

Ed è stato fatto molto rapidamente!


0

Se si dispone dello spazio libero, archiviarli in un singolo file .tar (senza compressione più veloce), quindi spostare il file sopra e annullare l'archiviazione.


0

La natura della destinazione determinerebbe il modo più efficiente per svolgere questo compito. Supponiamo che tu sia su un sistema locale, il tuo PWDè /adesso. e /acontiene milioni di immagini. Il nostro compito è spostare tutte le immagini /b, mantenendo al contempo tutta la struttura della sottodirectory. Supponiamo anche /ae /bsono punti di montaggio per due diverse partizioni, ciascuna su un disco collegato localmente. Vorremmo fare questo compito con un telo. Questo potrebbe richiedere un certo tempo, in modo da assicurarsi che si sta utilizzando screen, tmuxoppure eseguire questo come un processo in background.

tar -C /a -cf . | tar -C /b -xf -

Che sarebbe copiare tutti i file e le directory in /aa /b, così ora è necessario ripulire /auna volta si conferma che a termine senza errori.

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.