Saya akan menyarankan untuk menggunakan opsi filter rsync. Sebagai contoh Anda cukup ketik:
rsync -vam -f'+ *[Nn][Aa][Mm][E]*' -f'+ */' -f'- *' a b
aturan filter pertama memberi tahu rsync pola apa yang harus disertakan. Aturan kedua diperlukan untuk memberi tahu rsync untuk memeriksa semua direktori pada traversalnya. Untuk mencegah direktori kosong dimasukkan, mereka dikecualikan secara eksplisit oleh -m
pilihan. Aturan filter terakhir memberi tahu rsync untuk membuang semua sisa pola yang sejauh ini masih belum cocok.
rsync tidak berbicara regex. Anda dapat mendaftarkan find dan grep, meskipun agak misterius. Untuk menemukan file target:
find a/ |
grep -i 'name'
Tapi semuanya diawali dengan "a/" - yang masuk akal, tetapi yang ingin kita akhiri adalah daftar pola penyertaan yang dapat diterima untuk rsync, dan karena awalan "a/" tidak berfungsi untuk rsync I' akan menghapusnya dengan cut:
find . |
grep -i 'name' |
cut -d / -f 2-
Masih ada masalah - kami masih akan melewatkan file di subdirektori, karena rsync tidak mencari direktori di daftar pengecualian. Saya akan menggunakan awk untuk menambahkan subdirektori dari file yang cocok ke daftar pola penyertaan:
find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'
Yang tersisa hanyalah mengirim daftar ke rsync - kita dapat menggunakan argumen --include-from=- untuk memberikan daftar pola ke rsync pada input standar. Jadi, semuanya:
find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/
Perhatikan bahwa direktori sumber 'a' dirujuk melalui dua jalur yang berbeda - "a/" dan "./a/". Ini halus tapi penting. Untuk membuatnya lebih konsisten, saya akan membuat satu perubahan terakhir, dan selalu merujuk ke direktori sumber sebagai "./a/". Namun, ini berarti perintah cut harus diubah karena akan ada tambahan "./" di depan hasil dari find:
find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/
Jika Anda menggunakan ZSH maka Anda dapat menggunakan flag (#i) untuk mematikan sensitivitas huruf besar-kecil. Contoh:
$ touch NAME
$ ls (#i)*name*
NAME
ZSH juga mendukung pengecualian, yang ditentukan seperti jalur reguler tetapi memiliki ~
awal$ touch aa ab ac
$ ls *~*c
aa ab
Anda dapat menghubungkan pengecualian:
$ ls *~*c~*b
aa
Terakhir, Anda dapat menentukan jenis file yang ingin dikembalikan (direktori, file, dll). Ini dilakukan dengan (/) untuk direktori dan (.) untuk file.
$ touch file
$ mkdir dir
$ ls *(.)
file
Berdasarkan semua ini, saya akan melakukan perintah itu sebagai:
rsync -avvz *(/) (#i)*name* ./a/ ./b/
(Saya tidak melihat perlunya pengecualian dengan pemilih ini)