sincronizzare un elenco di directory con percorso assoluto nel file di testo


9

Ho un file di testo contenente un elenco di directory con il suo percorso assoluto

$ cat DirectoriesToCopy.txt

/data/Dir1
/data/Dir2

Voglio usare rsync per copiare tutte queste directory preservando il suo percorso assoluto in un'altra posizione.

Ho provato il seguente comando rsync, ma non funziona

rsync -avr --include-from=DirectoriesToCopy.txt --exclude='*/' --exclude='/*'  /  /media/MyDestination/

Cosa non va qui?


Vuoi trasferire /data/Dir1e /data/Dir2includere i loro contenuti su /media/MyDestination/Dir1e /media/MyDestination/Dir2? O vuoi includere la /dataparte? Quanto è grande questo elenco, è troppo grande per elencare semplicemente quelle voci sulla riga di comando? Ad ogni modo, le tue --excludedichiarazioni impediscono la ricorsione.
Wurtel,

Voglio trasferire anche tutti i file all'interno di quelle directory. Ci sono molti file in quella directory, quindi vorrei evitare di creare un altro file di testo con tutti i nomi di file.
Indiajoe,

Vorrei mantenere il mio percorso completo come /media/MyDestination/data/Dir2/. Ho aggiunto --exclude per impedire che altre directory e file in / vengano copiati.
Indiajoe,

Nei casi in cui l'elenco delle directory non è molto ampio, immagino che la seguente opzione sia più semplicersync -av $(cat DirectotiesToCopy.txt) /media/MyDestination/
indiajoe,

Risposte:


6

Utilizzare il comando seguente:

rsync -av --include-from=DirectoriesToCopy.txt --include /data/ --exclude='/data/*' --exclude='/*/' / /media/MyDestination/

Devi includere / data / esplicitamente, potresti anche averlo aggiunto all'elenco nel file. Quindi escludi tutte le altre directory (l'ordine è importante con include / exclude).

Si noti che l'utilizzo di è -rstato ridondante in quanto incluso in -a.

EDIT: potresti anche ottenere lo stesso risultato con:

rsync -av --relative /data/Dir1 /data/Dir2 /media/MyDestination/

Non è rsync che ti costringe a fare cose difficili solo per copiare un paio di directory, ti dà solo diversi modi di fare la stessa cosa; in alcuni casi, andare nel modo include / exclude potrebbe essere più adatto, qui farei la cosa --relativa sopra (senza che --relativetu finisca con /media/MyDestination/Dir1e /media/MyDestination/Dir2, con --relativel'intero percorso sorgente sia copiato nella destinazione).


Grazie che ha funzionato. Sono un po 'sorpreso che si debba definire una sequenza di filtri così attenta per copiare semplicemente un elenco di directory usando rsync. Ad esempio, se il mio elenco di directory non si trovava in una directory / dati / comuni ma fosse invece diffuso in molte posizioni, i filtri da definire diventano piuttosto complicati.
Indiajoe,

Vedi la mia modifica alla mia risposta.
Wurtel,

Grazie. Quindi se il mio elenco di directory non è molto grande, potrei usare il flag --relative come mostrato sotto. rsync -av --relative $(cat DirectotiesToCopy.txt) /media/MyDestination/
Indiajoe,

Sì; tenere a mente --relativeè solo un'altra opzione.
Wurtel,

7

Voglio usare rsync per copiare tutte queste directory [da un elenco] preservandone il percorso assoluto in un'altra posizione

Non usare --includeo --filtervariazioni, poiché ciò confonderà semplicemente le cose. Invece, usa --files-from=_filename_. (Se lo fai, assicurati di fare molti test.)

  1. Crea l'elenco di directory in un file, una directory / file per riga.

  2. Usa rsync's --files-from=con il file sopra.

  3. Utilizzare l' opzione --relative/ -Rper assicurarsi che i nomi dei percorsi di origine vengano copiati alla fine della destinazione.

  4. Anche se hai l' -aopzione, includi anche -r. Dalla pagina man:

    In entrambi i casi, se l'opzione -r fosse abilitata, anche l'intera gerarchia di quella directory verrebbe trasferita (tenere presente che -r deve essere specificato esplicitamente con --files-from, poiché non è implicito da -a).

Comando completo:

rsync ${DEBUG:+-nv} -arR --files-from=<list_of_files.txt> <top-level-dir>  <target-dir>

(i file in list_of_files.txt devono essere relativi o trovati nella directory principale )

(se DEBUG è impostato, rsync stampa semplicemente ciò che potrebbe essere stato copiato.)


1
Questo è quello di cui avevo bisogno! Comunque "--include-from" dovrebbe essere "--files-from". Inoltre ho usato "--list-only" per vedere un'anteprima di ciò che RSYNC farà prima di farlo funzionare.
Adambean,

1
Grazie, ho aggiornato la risposta. --include-fromfunzionerà anche, ma poi quello che ho detto -rè in gran parte irrilevante.
Otheus,

2

Il manuale di rsync avverte di questo scenario (sezione "Includi / escludi regole modello"):

questo non funzionerà:

+ /some/path/this-file-will-not-be-found
+ /file-is-included
- *

Ciò fallisce perché la directory padre "some"è esclusa dalla '*'regola, quindi rsync non visita mai nessuno dei file nelle directory "some"o "some/path". Una soluzione è chiedere l'inclusione di tutte le directory nella gerarchia utilizzando un'unica regola: "+ */"(inserirla prima della "- *"regola) e forse utilizzare l' --prune-empty-dirsopzione. Un'altra soluzione è aggiungere regole di inclusione specifiche per tutte le directory principali che devono essere visitate. Ad esempio, questo set di regole funziona bene:

+ /some/
+ /some/path/
+ /some/path/this-file-is-found
+ /file-also-included
- *

Nel tuo caso, credo che l'approccio più semplice sarebbe quella di preprocessare l'elenco delle directory per includere in modo che ogni volta che si include /path/to/foo, si includono anche tutte le directory principali ( /path/to, /path, /), e comprendono anche le sottodirectory delle directory originali ( /path/to/foo/***), e dopo tutto ciò ha una regola che esclude tutto ciò che non è stato precedentemente elencato ( *).

<DirectoriesToCopy.txt awk '
    {print "+ " $0 "/***"; while (sub(/\/+[^\/]+\/*$/, "/")) print "+ " $0}
    END {print "- *"}
' >rsync-rules.txt
rsync -avr --include-from=rsync-rules.txt  /  /media/MyDestination/

Grazie per la spiegazione dettagliata e lo script per creare il file delle regole. Ora capisco il problema. Sento ancora che sarebbe stato bello che rsync avesse un'opzione come --dirs-from = DirectoriesToCopy.txt come scorciatoia per tutti i filtri complicati.
Indiajoe,
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.