GNU/Linux >> Belajar Linux >  >> Linux

rsync menggunakan regex untuk menyertakan hanya beberapa file

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)


Linux
  1. Bagaimana Cara Mengganti Nama Banyak File Menggunakan Regex?

  2. Mencatat Hanya File yang Ditransfer Dengan Rsync?

  3. Cara menyalin direktori secara rekursif menggunakan rsync sambil mengecualikan file tertentu

  1. Menggunakan Rsync sertakan dan kecualikan opsi untuk menyertakan direktori dan file berdasarkan pola

  2. rsync hanya menyalin jenis file tertentu menggunakan opsi sertakan

  3. Bagaimana saya bisa mendaftar hanya file yang tidak kosong menggunakan ls?

  1. Rsync, Hanya Sertakan Jenis File Tertentu Tidak Termasuk Beberapa Direktori?

  2. Bagaimana Cara Selektif Membungkam Rsync?

  3. Transfer SCP hanya mengubah file