Zde je důležitá část manuálové stránky:
Když je sestavován seznam souborů/adresářů k přenosu, rsync postupně kontroluje každý název, který se má přenést, se seznamem vzorů zahrnout/vyloučit a podle prvního shodného vzoru se pracuje:pokud se jedná o vzor vyloučení, pak je tento soubor přeskočeno; pokud se jedná o vzor zahrnutí, pak tento název souboru není přeskočen; pokud není nalezen žádný odpovídající vzor, nebude název souboru přeskočen.
Abych to shrnul:
- Neodpovídá žádnému vzoru znamená, že soubor bude zkopírován!
- Algoritmus se ukončí, jakmile se jakýkoli vzor shoduje
Také něco, co končí lomítkem, odpovídá adresářům (jako find -type d
by).
Rozeberme tuto odpověď shora.
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
- Nepřeskakujte žádné adresáře
- Nepřeskakujte žádné
.sh
soubory - Přeskočit vše
- (Implicitně nic nepřeskakujte, ale výše uvedené pravidlo brání tomu, aby se výchozí pravidlo vůbec stalo.)
Nakonec --prune-empty-directories
zachovává první pravidlo, aby se všude nevytvářely prázdné adresáře.
Myslím, že --include
se používá k zahrnutí podmnožiny souborů, které jsou jinak vyloučeny --exclude
, spíše než zahrnout pouze tyto soubory. Jinými slovy:musíte myslet na zahrnout což znamená nevylučovat .
Zkuste místo toho:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
Pro rsync verze 3.0.6 nebo vyšší je třeba objednávku upravit následovně (viz komentáře):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Přidání -m
flag zabrání vytváření prázdných adresářových struktur v cíli. Testováno ve verzi 3.1.2.
Pokud tedy chceme pouze soubory *.sh, musíme vyloučit všechny soubory --exclude="*"
, zahrnout všechny adresáře --include="*/"
a zahrnout všechny soubory *.sh --include="*.sh"
.
Některé dobré příklady najdete v sekci Pravidla pro zahrnutí/vyloučení vzorů manuálové stránky
Ještě dodatek:pokud potřebujete synchronizovat soubory podle jejich přípon v pouze jeden adresář (bez rekurze) měli byste použít takovou konstrukci:
rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/
Věnujte pozornost tečce v prvních --include
. --no-r
v této konstrukci nefunguje.
UPRAVIT:
Děkujeme gbyte.co za cenný komentář!
UPRAVIT:
-uzv
příznaky s touto otázkou přímo nesouvisí, ale zahrnul jsem je, protože je obvykle používám.
Odpověď @chepner zkopíruje všechny podadresáře, ať už obsahuje soubory nebo ne. Pokud potřebujete vyloučit podadresáře, které neobsahují soubor a přesto zachovat adresářovou strukturu, použijte
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"