Rsync, zawiera tylko niektóre typy plików z wyłączeniem niektórych katalogów

14

Chcę synchronizować tylko niektóre typy plików (np. .py) I chcę wykluczyć pliki z niektórych katalogów (np venv.).

Oto, co próbowałem:

rsync -avz --include='*/' --exclude='venv/' --include='*.py' --exclude='*' /tmp/src/ /tmp/dest/

Ale to nie działa.

czego mi brakuje?

Odpowiedziałem też na to pytanie, ale to nie pomogło.

CentAu
źródło
dlaczego potrzebujesz inicjału --include='*/'?
Charlie Parker
1
Jak wykonać polecenie, jeśli mam rekurencyjne katalogi, które chcę wysłać tylko jeden typ pliku. Wydaje się, że robi to tylko dla katalogu docelowego, prawdopodobnie z powodu ostatniego wykluczenia, które wyklucza wszystko
Charlie Parker

Odpowiedzi:

17

venv/należy wykluczyć, zanim */ zostanie uwzględniony:

rsync -avz --exclude='venv/' --include='*/' --include='*.py' --exclude='*' /tmp/src/ /tmp/dest/

Subtelność polega na tym rsync, że przetwarza reguły w kolejności i wygrywa pierwsza pasująca reguła. Tak więc, jeśli --include='*/'jest wcześniej --exclude='venv/', katalog venv/jest uwzględniony przez --include='*/'i reguła wykluczenia nigdy nie jest sprawdzana.

Czy możemy to uprościć?

Dlaczego potrzebujemy --include='*/'i --exclude='*'? Dlaczego nie --exclude=venv/ --include='*.py'wystarcza?

Domyślnie dołączane są pliki / katalogi. Zastanów się:

rsync -avz --exclude='venv/' --include='*.py' source target

Obejmuje to wszystko oprócz plików lub katalogów w venv/. Ty jednak potrzebujesz tylko .pyplików. Oznacza to, że musimy jawnie wykluczyć inne pliki za pomocą --exclude='*'.

--exclude='*'wyklucza zarówno pliki, jak i katalogi. Jeśli więc określimy --exclude='*', wszystkie katalogi zostaną wykluczone i .pyzostaną znalezione tylko pliki z katalogu głównego. .pypliki w podkatalogach nigdy nie zostaną znalezione, ponieważ rsyncnie przeglądają wykluczonych katalogów. Tak więc, jeśli mamy --exclude='*', musimy go poprzedzić, --include='*/'aby zapewnić zbadanie zawartości wszystkich katalogów.

John1024
źródło
Świetny! Dzięki! Dla mojego zrozumienia, dlaczego potrzebujemy --include='*/'i --exclude='*'? Dlaczego tylko --exclude=venv/ --include='*.py'nie działa?
CentAu,
1
@CentAu Właśnie zaktualizowałem odpowiedź, dyskutując o tym.
John1024
Jak wykonać polecenie, jeśli mam rekurencyjne katalogi, które chcę wysłać tylko jeden typ pliku. Wydaje się, że robi to tylko dla katalogu docelowego, prawdopodobnie z powodu ostatniego wykluczenia, które wyklucza wszystko.
Charlie Parker
1
Zakładki! Specjalnie dla subtelności. Nie mogę wymyślić żadnego innego narzędzia CLI, w którym kolejność flag w ogóle ma znaczenie!
antortjim