GNU/Linux >> Linux Esercitazione >  >> Linux

rsync usando regex per includere solo alcuni file

Suggerirei di utilizzare l'opzione filtro di rsync. Per il tuo esempio digita semplicemente:

rsync -vam -f'+ *[Nn][Aa][Mm][E]*' -f'+ */' -f'- *' a b

la prima regola di filtro indica a rsync quali pattern includere. La seconda regola è necessaria per dire a rsync di ispezionare tutte le directory durante il suo attraversamento. Per impedire l'inclusione delle directory vuote, vengono escluse esplicitamente da -m opzione. L'ultima regola di filtro dice a rsync di eliminare tutti i modelli rimanenti che ancora non corrispondevano.


rsync non parla regex. Puoi arruolare find e grep, anche se diventa un po' arcano. Per trovare i file di destinazione:

find a/ |
grep -i 'name'

Ma hanno tutti il ​​prefisso "a/" - il che ha senso, ma quello che vogliamo ottenere è un elenco di modelli di inclusione accettabili per rsync, e poiché il prefisso "a/" non funziona per rsync I' lo rimuoverò con cut:

find . |
grep -i 'name' |
cut -d / -f 2-

C'è ancora un problema:mancheremo ancora i file nelle sottodirectory, perché rsync non cerca le directory nell'elenco di esclusione. Userò awk per aggiungere le sottodirectory di tutti i file corrispondenti all'elenco dei modelli di inclusione:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'

Non resta che inviare l'elenco a rsync:possiamo utilizzare l'argomento --include-from=- per fornire un elenco di pattern a rsync sullo standard input. Quindi, nel complesso:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

Si noti che la directory di origine 'a' viene indicata tramite due percorsi diversi:"a/" e "./a/". Questo è sottile ma importante. Per rendere le cose più coerenti, farò un'ultima modifica e farò sempre riferimento alla directory dei sorgenti come "./a/". Tuttavia, questo significa che il comando cut deve cambiare poiché ci sarà un "./" in più davanti ai risultati di find:

find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

Se usi ZSH, puoi usare il flag (#i) per disattivare la distinzione tra maiuscole e minuscole. Esempio:

$ touch NAME
$ ls (#i)*name*
NAME

ZSH supporta anche le esclusioni, che sono specificate proprio come il normale percorso ma hanno un ~

iniziale
$ touch aa ab ac
$ ls *~*c
aa ab

Puoi concatenare le esclusioni:

$ ls *~*c~*b
aa

Infine puoi specificare che tipo di file vuoi restituire (directory, file, ecc.). Questo viene fatto con (/) per directory e (.) per file.

$ touch file
$ mkdir dir
$ ls *(.)
file

Sulla base di tutto questo, farei quel comando come:

rsync -avvz *(/) (#i)*name* ./a/ ./b/

(Non vedo la necessità di un'esclusione con questi selettori)


Linux
  1. Come inviare e scaricare file utilizzando Rsync

  2. Eseguire il backup dei file con rsync

  3. Come copiare le directory in modo ricorsivo utilizzando rsync escludendo file specifici

  4. Come cercare i file usando regex nello script della shell linux

  5. rsync copia solo su determinati tipi di file utilizzando l'opzione include

Riprendi i file parzialmente trasferiti su SSH utilizzando Rsync

Come eseguire il backup di file e directory utilizzando Rsync in Linux

Rsync, includi solo alcuni tipi di file escluse alcune directory?

Come silenziare selettivamente Rsync?

Trasferisci file usando WinSCP

Utilizzando le opzioni di inclusione ed esclusione di Rsync per includere directory e file in base al modello