GNU/Linux >> Znalost Linux >  >> Linux

rsync pomocí regulárního výrazu k zahrnutí pouze některých souborů

Navrhoval bych použít možnost filtrování rsync. Pro váš příklad stačí napsat:

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

první pravidlo filtru říká rsync, jaké vzory má zahrnout. Druhé pravidlo je potřeba k tomu, abyste řekli rsync, aby zkontroloval všechny adresáře při průchodu. Aby se zabránilo zahrnutí prázdných adresářů, jsou explicitně vyloučeny pomocí -m volba. Poslední pravidlo filtru říká rsync, aby zlikvidoval všechny zbývající vzory, které se dosud neshodovaly.


rsync nemluví regulární výraz. Můžete zařadit find a grep, i když to bude trochu tajemné. Chcete-li najít cílové soubory:

find a/ |
grep -i 'name'

Ale všechny mají předponu "a/" - což dává smysl, ale chceme skončit seznamem vzorů začlenění přijatelných pro rsync, a protože předpona "a/" pro rsync nefunguje, I' odstraníte jej řezem:

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

Stále existuje problém - stále nám budou chybět soubory v podadresářích, protože rsync neprohledává adresáře v seznamu výjimek. Použiji awk k přidání podadresářů všech odpovídajících souborů do seznamu vzorů začlenění:

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

Zbývá pouze odeslat seznam do rsync - můžeme použít argument --include-from=- k poskytnutí seznamu vzorů pro rsync na standardním vstupu. Takže celkem:

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

Všimněte si, že na zdrojový adresář 'a' se odkazuje dvěma různými cestami - "a/" a "./a/". To je jemné, ale důležité. Aby byly věci konzistentnější, udělám jednu poslední změnu a vždy budu odkazovat na zdrojový adresář jako "./a/". To však znamená, že příkaz cut se musí změnit, protože na přední straně výsledků z find bude navíc "./":

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

Pokud používáte ZSH, můžete pomocí příznaku (#i) vypnout rozlišování malých a velkých písmen. Příklad:

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

ZSH také podporuje výjimky, které jsou specifikovány stejně jako běžná cesta, ale mají počáteční ~

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

Vyloučení můžete řetězit:

$ ls *~*c~*b
aa

Nakonec můžete určit, jaký druh souboru chcete vrátit (adresář, soubor atd.). To se provádí pomocí (/) pro adresář a (.) pro soubor.

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

Na základě toho všeho bych ten příkaz udělal jako:

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

(Nevidím potřebu vyloučení s těmito selektory)


Linux
  1. Jak přejmenovat spoustu souborů pomocí Regex?

  2. Protokolovat pouze přenesené soubory pomocí Rsync?

  3. Jak selektivně umlčet Rsync?

  1. Jak odesílat a stahovat soubory pomocí Rsync

  2. rsync kopíruje pouze určité typy souborů pomocí volby include

  3. cp -r bez skrytých souborů

  1. Jak mohu pomocí ls vypsat pouze neprázdné soubory?

  2. rsync N nejnovějších souborů v adresáři

  3. SCP přenáší pouze upravené soubory