rsync menyalin hanya beberapa jenis file menggunakan opsi penyertaan
110
Saya menggunakan skrip bash berikut untuk menyalin hanya file dengan ekstensi tertentu (dalam hal ini * .sh), namun masih menyalin semua file. apa yang salah?
dari = $ 1
menjadi = $ 2
rsync -zarv --include = "*. sh" $ dari $ ke
Meskipun tidak secara tegas terkait, saya sarankan mengutip $ dari / $ ke. Tidak melakukannya dapat memberikan hasil yang tidak diharapkan jika argumen posisi 1/2 menyertakan spasi.
Kjetil Joergensen
apakah Anda mendapatkan pemahaman mengapa perintah Anda tidak berfungsi?
Charlie Parker
@CharlieParker: Apakah Anda harus menggunakan rsync, ini dapat dicapai dengan sangat baik dengan internal shell?
Inian
Apa kekurangan dari pertanyaan ini dan jawabannya adalah bagaimana membuat perintah jika saya memiliki direktori rekursif yang ingin saya kirim hanya satu jenis file. Tampaknya itu hanya melakukannya untuk direktori target ...
Charlie Parker
Jawaban:
200
Saya pikir --includedigunakan untuk menyertakan subset file yang dikecualikan oleh --exclude, daripada hanya menyertakan file-file itu. Dengan kata lain: Anda harus memikirkan tentang memasukkan makna, jangan mengecualikan .
Menambahkan -mbendera akan menghindari pembuatan struktur direktori kosong di tujuan. Diuji dalam versi 3.1.2.
Jadi jika kita hanya ingin file * .sh kita harus mengecualikan semua file --exclude="*", termasuk semua direktori --include="*/"dan menyertakan semua file * .sh --include="*.sh".
Anda dapat menemukan beberapa contoh bagus di bagian Sertakan / Kecualikan Aturan Pola di halaman manual
Meskipun itu akan memberi Anda semua sub-direktori, jika ada file .sh di subdirektori yang ingin Anda rsync, kemungkinan Anda juga ingin menggunakan --include = "* /".
Kjetil Joergensen
50
Saya mencoba ini di rsync versi 3.0.7, yang saya dapatkan sejak lama dari macports, dan itu tidak berfungsi dengan urutan include / excludes ini. Ini adalah apa yang saya berakhir dengan yang bekerja untuk saya (diadaptasi untuk OP): rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to".
Bijou Trouvaille
3
Saya mencoba dengan rsync 3.0.9 dan tidak berhasil. Bijou benar, --include=\*.sh--exclude=\*
urutannya
3
Perhatikan bahwa Anda selalu dapat mengeklik edit dan menyarankan edit untuk jawabannya :)
Achal Dave
2
Ini tidak berfungsi dengan urutan penyertaan / pengecualian Anda, tetapi berfungsi dengan urutan yang disarankan oleh Bijou Trouvaille
John Smith Opsional
57
Jawaban oleh @chepner akan menyalin semua sub-direktori terlepas dari fakta apakah itu berisi file atau tidak. Jika Anda perlu mengecualikan sub-direktori yang tidak berisi file dan masih mempertahankan struktur direktori, gunakan
Ini adalah persyaratan bagi saya: "Jika Anda perlu mengecualikan sub-direktori yang tidak berisi file dan masih mempertahankan struktur direktori" +1
Juuso Ohtonen
1
Saya tidak mengerti bagaimana Anda tahu apa urutan --includes?
Charlie Parker
1
Bagaimana seseorang membuat perintah jika saya memiliki direktori rekursif yang ingin saya kirim hanya satu jenis file. Tampaknya itu hanya melakukannya untuk direktori target.
Charlie Parker
15
Satu lagi tambahan: jika Anda perlu menyinkronkan file dengan ekstensinya dalam satu dir saja (tanpa rekursi) Anda harus menggunakan konstruksi seperti ini:
bagaimana Anda tahu bagaimana urutan bendera itu dan apa yang perlu disertakan?
Charlie Parker
1
@CharlieParker, karena rsync menggunakan opsi includedan excludedalam urutan yang ditentukan. Selain itu , rsync berhenti pada opsi pertama yang cocok. Jadi, jika kita menentukan --exclude '*'tempat pertama dalam contoh ini, rsync tidak akan melakukan apa-apa. Temui pria itu untuk penjelasan lebih lanjut.
Serge Roussak
bisakah Anda menjelaskan kepada saya apa yang dilakukan setiap bendera? Bendera pertama -- include './' mengatakan sertakan semua yang ada di jalur direktori sumber? Kemudian yang berikutnya `--include '.ext'` menyertakan file tertentu di jalur sumber bernama .extdan kemudian exclude mengatakan jangan kirim yang lain --exclude '*'? Apakah itu benar?
Charlie Parker
1
Bagaimana seseorang membuat perintah jika saya memiliki direktori rekursif yang ingin saya kirim hanya satu jenis file. Tampaknya itu hanya melakukannya untuk direktori target.
Charlie Parker
1
Terima kasih untuk ini! Perlu --include '*.ext'dan tidak--include '.ext'
gbyte
13
Inilah bagian penting dari halaman manual:
Karena daftar file / direktori yang akan ditransfer dibuat, rsync memeriksa setiap nama yang akan ditransfer terhadap daftar pola sertakan / kecualikan secara bergantian, dan pola pencocokan pertama dijalankan: jika itu adalah pola pengecualian, maka file itu adalah dilewati; jika itu adalah pola penyertaan maka nama file itu tidak akan dilewati; jika tidak ditemukan pola yang cocok, maka nama file tidak akan dilewati.
Untuk meringkas:
Tidak cocok dengan pola apa pun berarti file akan disalin!
Algoritme berhenti setelah ada pola yang cocok
Juga, sesuatu yang diakhiri dengan garis miring adalah direktori yang cocok (seperti find -type dakan).
Terima kasih banyak telah menjelaskan apa yang terjadi. Sekarang ada kemungkinan lebih baik bahwa saya tidak akan melupakan perintah itu.
MohamedEzz
3
"Algoritme berhenti setelah pola apa pun cocok" - ini adalah kuncinya, dan tidak ada jawaban yang berperingkat lebih tinggi yang menjelaskannya sejelas dan sejelas yang Anda lakukan di sini. Tentu saja ini ada di halaman manual di sana, dan jika saya Saya sudah membaca semuanya dengan cermat, saya sudah melihatnya. Tetap saja, terima kasih.
TheDudeAbides
0
Jika seseorang mencari ini ... Saya hanya ingin melakukan rsync file dan folder tertentu dan berhasil melakukannya dengan perintah ini: rsync --include-from=rsync-files
Tulis fungsi praktis ini dan masukkan skrip bash saya atau ~/.bash_aliases. Menguji sinkronisasi secara lokal di Linux dengan bash dan awkdiinstal. Berhasil
selrsync(){# selective rsync to sync only certain filetypes;# based on: https://stackoverflow.com/a/11111793/588867# Example: selrsync 'tsv,csv' ./source ./target --dry-run
types="$1"; shift;#accepts comma separated list of types. Must be the first argument.
includes=$(echo $types| awk -F',' \
'BEGIN{OFS=" ";}
{
for (i = 1; i <= NF; i++ ) { if (length($i) > 0) $i="--include=*."$i; } print
}')
restargs="$@"
echo Command: rsync -avz --prune-empty-dirs --include="*/" $includes --exclude="*""$restargs"eval rsync -avz --prune-empty-dirs --include="*/""$includes"--exclude="*" $restargs
}
Avantages:
singkat praktis dan dapat diperluas ketika seseorang ingin menambahkan lebih banyak argumen (yaitu --dry-run).
rsync
, ini dapat dicapai dengan sangat baik dengan internal shell?Jawaban:
Saya pikir
--include
digunakan untuk menyertakan subset file yang dikecualikan oleh--exclude
, daripada hanya menyertakan file-file itu. Dengan kata lain: Anda harus memikirkan tentang memasukkan makna, jangan mengecualikan .Coba saja:
Untuk rsync versi 3.0.6 atau lebih tinggi, urutan perlu dimodifikasi sebagai berikut (lihat komentar):
Menambahkan
-m
bendera akan menghindari pembuatan struktur direktori kosong di tujuan. Diuji dalam versi 3.1.2.Jadi jika kita hanya ingin file * .sh kita harus mengecualikan semua file
--exclude="*"
, termasuk semua direktori--include="*/"
dan menyertakan semua file * .sh--include="*.sh"
.Anda dapat menemukan beberapa contoh bagus di bagian Sertakan / Kecualikan Aturan Pola di halaman manual
sumber
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
.--include=\*.sh
--exclude=\*
Jawaban oleh @chepner akan menyalin semua sub-direktori terlepas dari fakta apakah itu berisi file atau tidak. Jika Anda perlu mengecualikan sub-direktori yang tidak berisi file dan masih mempertahankan struktur direktori, gunakan
sumber
Satu lagi tambahan: jika Anda perlu menyinkronkan file dengan ekstensinya dalam satu dir saja (tanpa rekursi) Anda harus menggunakan konstruksi seperti ini:
Perhatikan titik di awal
--include
.--no-r
tidak berfungsi dalam konstruksi ini.EDIT:
Terima kasih kepada gbyte.co untuk komentarnya yang berharga!
sumber
include
danexclude
dalam urutan yang ditentukan. Selain itu , rsync berhenti pada opsi pertama yang cocok. Jadi, jika kita menentukan--exclude '*'
tempat pertama dalam contoh ini, rsync tidak akan melakukan apa-apa. Temui pria itu untuk penjelasan lebih lanjut.-- include './'
mengatakan sertakan semua yang ada di jalur direktori sumber? Kemudian yang berikutnya `--include '.ext'` menyertakan file tertentu di jalur sumber bernama.ext
dan kemudian exclude mengatakan jangan kirim yang lain--exclude '*'
? Apakah itu benar?--include '*.ext'
dan tidak--include '.ext'
Inilah bagian penting dari halaman manual:
Untuk meringkas:
Juga, sesuatu yang diakhiri dengan garis miring adalah direktori yang cocok (seperti
find -type d
akan).Mari kita pisahkan jawaban ini dari atas.
.sh
file apa punAkhirnya,
--prune-empty-directories
menjaga aturan pertama dari membuat direktori kosong di semua tempat.sumber
Jika seseorang mencari ini ... Saya hanya ingin melakukan rsync file dan folder tertentu dan berhasil melakukannya dengan perintah ini:
rsync --include-from=rsync-files
Dengan file rsync:
sumber
Tulis fungsi praktis ini dan masukkan skrip bash saya atau
~/.bash_aliases
. Menguji sinkronisasi secara lokal di Linux dengan bash danawk
diinstal. BerhasilAvantages:
singkat praktis dan dapat diperluas ketika seseorang ingin menambahkan lebih banyak argumen (yaitu
--dry-run
).Contoh:
sumber