rsync daftar direktori dengan path absolut dalam file teks

9

Saya memiliki file teks yang berisi daftar direktori dengan jalur absolutnya

$ cat DirectoriesToCopy.txt

/data/Dir1
/data/Dir2

Saya ingin menggunakan rsync untuk menyalin semua direktori ini mempertahankan jalur absolutnya ke lokasi lain.

Saya mencoba perintah rsync berikut, tetapi tidak berhasil

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

Apa yang salah di sini?

indiajoe
sumber
Apakah Anda ingin mentransfer /data/Dir1dan /data/Dir2memasukkan kontennya ke /media/MyDestination/Dir1dan /media/MyDestination/Dir2? Atau Anda ingin memasukkan /databagian itu? Seberapa besar daftar ini, apakah terlalu besar untuk hanya mendaftarkan entri-entri pada baris perintah? Bagaimanapun, --excludepernyataan Anda mencegah rekursi.
Wurtel
Saya ingin mentransfer semua file di dalam direktori itu juga. Ada banyak file di direktori itu, jadi saya ingin menghindari membuat file teks lain dengan semua nama file.
indiajoe
Saya ingin menjaga jalur penuh saya seperti /media/MyDestination/data/Dir2/. Saya menambahkan --exclude untuk mencegah direktori dan file lain di / dari disalin.
indiajoe
Dalam kasus di mana daftar direktori tidak terlalu besar, saya kira opsi berikut ini lebih mudahrsync -av $(cat DirectotiesToCopy.txt) /media/MyDestination/
indiajoe

Jawaban:

6

Gunakan perintah berikut:

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

Anda perlu memasukkan / data / secara eksplisit, Anda juga bisa menambahkannya ke daftar di file. Kemudian kecualikan semua direktori lain (urutan penting dengan menyertakan / tidak termasuk).

Perhatikan bahwa penggunaan Anda -rberlebihan seperti yang termasuk dalam -a.

EDIT: Anda juga dapat mencapai hasil yang sama dengan:

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

Bukan rsync yang memaksa Anda untuk melakukan hal-hal sulit hanya dengan menyalin beberapa direktori, itu hanya memberi Anda banyak cara untuk melakukan hal yang sama; dalam beberapa kasus akan menyertakan / mengecualikan cara mungkin lebih cocok, di sini saya akan melakukan hal - relatif di atas (tanpa --relativeAnda akan berakhir dengan /media/MyDestination/Dir1dan /media/MyDestination/Dir2, dengan --relativeseluruh jalur sumber disalin ke tujuan).

Wurtel
sumber
Terima kasih, itu berhasil. Saya sedikit terkejut bahwa kita harus mendefinisikan urutan filter yang cermat untuk hanya menyalin daftar direktori menggunakan rsync. Sebagai contoh, jika daftar direktori saya tidak di bawah satu direktori / data umum / tetapi tersebar di banyak lokasi, filter untuk mendefinisikan menjadi sangat rumit.
indiajoe
Lihat edit saya untuk jawaban saya.
Wurtel
Terima kasih. Jadi, jika daftar direktori saya tidak terlalu besar, saya bisa menggunakan --relative flag seperti yang ditunjukkan di bawah ini. rsync -av --relative $(cat DirectotiesToCopy.txt) /media/MyDestination/
indiajoe
Iya; perlu diingat --relativehanyalah pilihan lain.
Wurtel
7

Saya ingin menggunakan rsync untuk menyalin semua direktori ini [dari daftar] mempertahankan jalur absolutnya ke lokasi lain

Jangan gunakan --includeatau --filtervariasi, karena itu hanya akan membingungkan hal-hal. Sebaliknya, gunakan --files-from=_filename_. (Jika ya, pastikan Anda melakukan banyak pengujian.)

  1. Buat daftar direktori dalam file, satu direktori / file per baris.

  2. Gunakan rsync --files-from=dengan file di atas.

  3. Gunakan --relative/ -Ropsi untuk memastikan nama path sumber disalin di akhir tujuan.

  4. Bahkan jika Anda memiliki -aopsi, sertakan juga -r. Dari halaman manual:

    Dalam kedua kasus, jika opsi -r diaktifkan, seluruh hierarki dir itu juga akan ditransfer (perlu diingat bahwa -r perlu ditentukan secara eksplisit dengan --files-from, karena tidak tersirat oleh -a).

Perintah lengkap:

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

(file dalam list_of_files.txt harus relatif atau ditemukan di dir level atas )

(jika DEBUG diatur, rsync hanya mencetak apa yang mungkin telah disalin.)

Otheus
sumber
1
Inilah yang saya butuhkan! Namun "--include-from" harus "--files-from". Saya juga menggunakan "--list-only" untuk melihat pratinjau dari apa yang akan dilakukan RSYNC sebelum benar-benar membuatnya bekerja.
Adambean
1
Terima kasih, saya telah memperbarui jawabannya. --include-fromjuga akan berfungsi, tetapi apa yang saya katakan -rsebagian besar tidak relevan.
Otheus
2

The pengguna rsync memperingatkan tentang skenario ini (bagian “Sertakan / mengecualikan aturan pola”):

ini tidak akan berhasil:

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

Ini gagal karena direktori induk "some"dikecualikan oleh '*'aturan, jadi rsync tidak pernah mengunjungi salah satu file di direktori "some"atau "some/path". Salah satu solusinya adalah meminta semua direktori dalam hierarki untuk dimasukkan dengan menggunakan aturan tunggal: "+ */"(letakkan di suatu tempat sebelum "- *"aturan), dan mungkin gunakan --prune-empty-dirsopsi. Solusi lain adalah menambahkan aturan menyertakan khusus untuk semua dir induk yang perlu dikunjungi. Misalnya, rangkaian aturan ini berfungsi dengan baik:

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

Dalam kasus Anda, saya pikir pendekatan sederhana akan preprocess daftar direktori untuk menyertakan sehingga setiap kali Anda memasukkan /path/to/foo, Anda juga mencakup semua direktori induk ( /path/to, /path, /), dan juga termasuk subdirektori dari direktori asli ( /path/to/foo/***), dan setelah semua ini memiliki aturan yang mengecualikan semua yang sebelumnya tidak terdaftar ( *).

<DirectoriesToCopy.txt awk '
    {print "+ " $0 "/***"; while (sub(/\/+[^\/]+\/*$/, "/")) print "+ " $0}
    END {print "- *"}
' >rsync-rules.txt
rsync -avr --include-from=rsync-rules.txt  /  /media/MyDestination/
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih atas penjelasan dan skrip terperinci untuk membuat file aturan. Saya mengerti masalahnya sekarang. Saya masih merasa akan lebih baik bagi rsync untuk memiliki opsi seperti --dirs-from = DirectoriesToCopy.txt sebagai jalan pintas ke semua filter yang rumit.
indiajoe