Próbuję utworzyć katalog, w którym będą przechowywane wszystkie i tylko moje pliki PDF skompilowane z LaTeX. Lubię trzymać każdy projekt w osobnym folderze, wszystkie w dużym folderze o nazwie LaTeX
. Więc próbowałem uruchomić:
rsync -avn *.pdf ~/LaTeX/ ~/Output/
które powinny znaleźć wszystkie pliki pdf ~/LaTeX/
i przenieść je do folderu wyjściowego. To nie działa Mówi mi, że nie znaleziono dopasowań dla „ *.pdf
”. Jeśli pominę ten filtr, polecenie wyświetla listę wszystkich plików we wszystkich folderach projektu w LaTeX. Jest to problem z filtrem * .pdf. Próbowałem zastąpić ~/
pełną ścieżką do mojego katalogu domowego, ale to nie przyniosło efektu.
Używam zsh. Próbowałem zrobić to samo w bash, a nawet z filtrem, który wyświetlał każdy pojedynczy plik w każdym podkatalogu ... Co się tutaj dzieje?
Dlaczego rsync nie rozumie mojego filtru tylko w formacie PDF?
DOBRZE. Więc zaktualizuj: Nie, próbuję
rsync -avn --include="*/" --include="*.pdf" LaTeX/ Output/
A to daje mi całą listę plików. Chyba dlatego, że wszystko pasuje do pierwszego wzoru ...
**
wzorca Zsh ) powinna jednak działać.Odpowiedzi:
TL, DR:
Rsync kopiuje źródło (źródła) do miejsca docelowego. Jeśli przekażesz
*.pdf
jako źródła, powłoka rozwija to do listy plików z.pdf
rozszerzeniem w bieżącym katalogu. Nie dzieje się żadne przechodzenie rekurencyjne, ponieważ nie przekazałeś żadnego katalogu jako źródła.Musisz więc uruchomić
rsync -a ~/LaTeX/ ~/Output/
, ale z filtrem, który każe rsync kopiować.pdf
tylko pliki. Reguły filtrowania Rsync mogą wydawać się zniechęcające podczas czytania instrukcji, ale możesz zbudować wiele przykładów za pomocą kilku prostych reguł.Włączenia i wyłączenia:
--exclude=*~
,--exclude=/some/relative/location
(w odniesieniu do argumentu źródłowego, np Wyklucza~/LaTeX/some/relative/location
).--include=*/
), a następnie wyklucz resztę za pomocą--exclude='*'
. To dlatego, że:--include='directory/***'
zrobi to.Wzory:
/
, odnosi się do nazwy pliku w katalogu sans./
, odnosi się tylko do katalogów./
, dotyczy całej ścieżki z katalogu, który został przekazany jako argumentrsync
.*
dowolny podciąg jednego komponentu katalogu (tzn. nigdy nie pasuje/
);**
dopasowuje dowolny podciąg ścieżki.Jeśli argument źródłowy kończy się na a
/
, jego zawartość jest kopiowana (rsync -r a/ b
tworzonab/foo
dla każdegoa/foo
). W przeciwnym razie sam katalog jest kopiowany (rsync -r a b
tworzyb/a
).Dlatego tutaj musimy uwzględnić
*.pdf
, uwzględnić katalogi zawierające je i wykluczyć wszystko inne.Zauważ, że powoduje to skopiowanie wszystkich katalogów, nawet tych, które nie zawierają pasującego pliku lub podkatalogu zawierającego jeden. Można tego uniknąć dzięki tej
--prune-empty-dirs
opcji (nie jest to rozwiązanie uniwersalne, ponieważ nie można wówczas skopiować katalogu, nawet poprzez jawne dopasowanie go, ale jest to rzadkie wymaganie).źródło
**
wzorca zsh ), to odtwarza strukturę katalogów w docelowym katalogu. Nie jestem pewien, czy tego właśnie chce OP…/etc/lsyncd/lsyncd.conf.lua
pliku. Masz jakiś pomysł?Domyślnie wszystko obejmuje, więc musisz jawnie wykluczyć wszystko po dołączeniu plików, które chcesz przenieść. Usuń --dry-run, aby faktycznie przesłać pliki.
Jeśli zaczniesz od:
Chciwe dopasowanie wykluczy wszystko od razu.
Jeśli spróbujesz:
Następnie przesyłane będą tylko pliki pdf w folderze najwyższego poziomu. Nie będzie podążał za żadnymi katalogami, ponieważ są one wykluczone przez „*”.
źródło
--prune-empty-dirs
(lub skrót-m
), zaoszczędzisz sobie nawet wiele pustych katalogów w miejscu docelowym, z tym wyjątkiem, że chcesz je jako przypomnienie lub schemat strukturalny./etc/lsyncd/lsyncd.conf.lua
pliku. Masz pomysł?Jeśli użyjesz wzorca podobnego
*.pdf
, powłoka „rozszerzy” ten wzorzec, tzn. Zastąpi wzorzec wszystkimi dopasowaniami w bieżącym katalogu. Uruchamiane polecenie (w tym przypadku rsync) nie wie o tym, że próbowałeś użyć wzorca.W przypadku korzystania z zsh istnieje jednak proste rozwiązanie:
**
wzorca można użyć do rekurencyjnego dopasowywania folderów. Spróbuj tego:źródło
rsync -avn ~/LaTeX/**/*.pdf ~/Output
, ale rozwiązanie z i tak--include
jest bardziej skalowalne.**
może się przydać także w innych sytuacjach.cd ~/Latex && cp -p **/*.pdf ~/Output
uniknąć błędu „zbyt długiego wiersza poleceń”.Aby rozwiązać problem, możesz użyć
find
pośredniej listy plików (files_to_copy
). Upewnij się, że jesteś w swoim katalogu domowym, a następnie:find LaTeX/ -type f -a -iname "*.pdf" > files_to_copy && rsync -avn --files-from=files_to_copy ~/ ~/Output/ && rm files_to_copy
Testowane z Bash.
źródło
-exec
opcji find lub użyciexargs
. Coś w stylu:find LaTeX/ -type f -iname "*.pdf" -print0 | xargs -0 -i rsync -avn {} Output/
standalone
lub nie ma.tex
pliku o tej samej nazwie, ponieważ będą to obrazy zawarte w niektórych dokumentach ...--files-from
akceptuje odczyt ze standardowego wejścia. To by zadziałałofind LaTeX/ -type f -a -iname "*.pdf" | rsync -avn --files-from=- ~/ ~/Output/
Sądząc po sekcji „OBEJMUJ / WYŁĄCZ ZASADY WZORU” na stronie podręcznika , sposobem na to jest
Krytyczną różnicą między tym a odpowiedzią kbrd jest
--include="*/"
flaga, która mówi rsync, aby poszła naprzód i skopiowała znalezione katalogi, bez względu na ich nazwę. Jest to konieczne, ponieważ rsync nie będzie się powtarzał w podkatalogu, chyba że otrzyma polecenie skopiowania tego podkatalogu.Zauważ też, że znaki cudzysłowu uniemożliwiają powłoce próbowanie rozwinięcia wzorców do nazw plików względem bieżącego katalogu i wykonanie jednej z następujących czynności:
Sukces i zepsucie filtra (niezbyt prawdopodobne w środku takiej flagi, chociaż tak naprawdę nigdy nie wiadomo, kiedy ktoś utworzy plik o nazwie
--include=foo.pdf
...)Niepowodzenie i potencjalnie generowanie błędu zamiast uruchamiania polecenia (tak jak odkryłeś, że domyślnie robi to zsh).
źródło
include
dodatkowe rzeczy już tam nic nie zmieniają. Jeśli rozumiesz, co mam na myśli ...--exclude="*"
po--include="*.pdf"
, albo to wszystko przeniesie.Co powiesz na to:
źródło
man rsync
umieszcza filtr po opcjach i przed źródłem / przeznaczeniem. Próbowałem tego i nie zadziałałoa
opcja dotyczy archiwizacji i powoduje, że kopiowanie jest rekurencyjne.Oto coś, co powinno działać bez użycia find. Różnica w stosunku do już opublikowanych odpowiedzi polega na kolejności reguł filtrowania. Reguły filtrowania w komendzie rsync działają podobnie jak reguły iptable, pierwsza reguła, do której pasuje plik, jest tą, która jest używana. Ze strony podręcznika :
Dlatego potrzebujesz następującego polecenia:
Zwróć uwagę na wzorzec „**. Pdf”. Według strony podręcznika :
W moim małym teście działa to rekurencyjnie w dół drzewa katalogów i wybiera tylko pliki pdf.
źródło
*.pdf
w katalogu najwyższego poziomu (ale nie~/LaTeX/foo/bar.pdf
).**
. Byłoby miło mieć tego przykład. ;)To jest moje preferowane rozwiązanie:
find
Polecenia jest łatwiejsza do zrozumienia niż włączania / wyłączania regułrsync
:-)Jeśli chcesz skopiować tylko pliki pdf, po prostu zmień
.jpg
na.pdf
źródło