Ich versuche, ein Verzeichnis zu erstellen, in dem alle und nur meine aus LaTeX kompilierten PDF-Dateien gespeichert werden. Ich mag es, jedes Projekt in einem separaten Ordner zu speichern, der sich alle in einem großen Ordner namens befindet LaTeX
. Also habe ich versucht zu rennen:
rsync -avn *.pdf ~/LaTeX/ ~/Output/
das sollte alle pdfs in finden ~/LaTeX/
und sie in den ausgabeordner übertragen. Das geht nicht. Es wird mir mitgeteilt, dass für " *.pdf
" keine Übereinstimmungen gefunden wurden . Wenn ich diesen Filter auslasse, listet der Befehl alle Dateien in allen Projektordnern unter LaTeX auf. Es ist also ein Problem mit dem * .pdf-Filter. Ich habe versucht, ~/
durch den vollständigen Pfad zu meinem Ausgangsverzeichnis zu ersetzen , aber das hatte keine Auswirkungen.
Ich benutze zsh. Ich habe versucht, dasselbe in bash und sogar mit dem Filter zu tun, der jede einzelne Datei in jedem Unterverzeichnis auflistet ... Was ist hier los?
Warum versteht rsync meinen PDF-Filter nicht?
OKAY. Also Update: Nein, ich versuche es
rsync -avn --include="*/" --include="*.pdf" LaTeX/ Output/
Und das gibt mir die ganze Dateiliste. Ich denke, weil alles zum ersten Muster passt ...
**
Muster) sollte funktionieren.Antworten:
TL, DR:
Rsync kopiert die Quelle (n) zum Ziel. Wenn Sie
*.pdf
als Quellen übergeben, erweitert die Shell dies auf die Liste der Dateien mit der.pdf
Erweiterung im aktuellen Verzeichnis. Es findet keine rekursive Durchquerung statt, da Sie kein Verzeichnis als Quelle übergeben haben.Sie müssen also ausführen
rsync -a ~/LaTeX/ ~/Output/
, aber mit einem Filter, um rsync anzuweisen,.pdf
nur Dateien zu kopieren . Die Filterregeln von Rsync können beim Lesen des Handbuchs entmutigend wirken, Sie können jedoch mit nur wenigen einfachen Regeln viele Beispiele erstellen.Ein- und Ausschlüsse:
--exclude=*~
,--exclude=/some/relative/location
(bezogen auf das Quellargument, zB Ausgeschlossen sind~/LaTeX/some/relative/location
).--include=*/
), und schließen Sie den Rest mit aus--exclude='*'
. Das ist weil:--include='directory/***'
wird das erledigt.Muster:
/
, gilt es für den Dateinamen sans directory./
, gilt es nur für Verzeichnisse./
, gilt es für den gesamten Pfad aus dem Verzeichnis, an das als Argument übergeben wurdersync
.*
ein beliebiger Teilstring einer einzelnen Verzeichniskomponente (dh er stimmt nie überein/
);**
Stimmt mit jedem Pfad-Teilstring überein.Wenn eine Quelle Argument mit einem Ende
/
, dessen Inhalt kopiert werden (rsync -r a/ b
erstelltb/foo
für jedena/foo
). Andernfalls wird das Verzeichnis selbst kopiert (rsync -r a b
erstelltb/a
).Daher müssen wir hier
*.pdf
Verzeichnisse einschließen , die sie enthalten, und alles andere ausschließen.Beachten Sie, dass hierdurch alle Verzeichnisse kopiert werden, auch diejenigen, die keine übereinstimmende Datei oder kein entsprechendes Unterverzeichnis enthalten. Dies kann mit der
--prune-empty-dirs
Option vermieden werden (dies ist keine universelle Lösung, da Sie dann ein Verzeichnis nicht einmal kopieren können, indem Sie es explizit abgleichen, dies ist jedoch eine seltene Anforderung).quelle
**
Muster von zsh ) wird hierdurch die Verzeichnisstruktur im Zielverzeichnis neu erstellt. Ich bin nicht sicher, ob dies das ist, was die OP will .../etc/lsyncd/lsyncd.conf.lua
Datei ausschließen. Hast du eine Idee?In der Standardeinstellung wird alles eingeschlossen, sodass Sie nach dem Einschließen der zu übertragenden Dateien explizit alles ausschließen müssen . Entfernen Sie den --dry-run, um die Dateien tatsächlich zu übertragen.
Wenn Sie anfangen mit:
Dann schließt das gierige Matching alles gleich aus.
Wenn du es versuchst:
Dann werden nur PDF-Dateien in den Ordner der obersten Ebene übertragen. Es folgen keine Verzeichnisse, da diese durch '*' ausgeschlossen sind.
quelle
--prune-empty-dirs
Verknüpfung hinzufügen, sparen-m
Sie sich sogar viele leere Verzeichnisse am Zielort, außer Sie möchten sie natürlich als Erinnerung oder strukturelle Blaupause./etc/lsyncd/lsyncd.conf.lua
Datei ausschließen. Hast du eine Idee?Wenn Sie ein Muster wie dieses verwenden
*.pdf
, „erweitert“ die Shell dieses Muster, dh sie ersetzt das Muster durch alle Übereinstimmungen im aktuellen Verzeichnis. Dem ausgeführten Befehl (in diesem Fall rsync) ist nicht bekannt, dass Sie versucht haben, ein Muster zu verwenden.Wenn Sie zsh verwenden , gibt es jedoch eine einfache Lösung: Das
**
Muster kann verwendet werden, um Ordner rekursiv abzugleichen. Versuche dies:quelle
rsync -avn ~/LaTeX/**/*.pdf ~/Output
, aber die Lösung mit--include
ist trotzdem skalierbarer.**
in anderen Situationen nützlich sein könnte.cd ~/Latex && cp -p **/*.pdf ~/Output
, um einen Fehler zu vermeiden, dass die Befehlszeile zu lang ist.Sie können
find
eine Zwischenliste von Dateien (files_to_copy
) verwenden, um Ihr Problem zu lösen. Stellen Sie sicher, dass Sie sich in Ihrem Home-Verzeichnis befinden.find LaTeX/ -type f -a -iname "*.pdf" > files_to_copy && rsync -avn --files-from=files_to_copy ~/ ~/Output/ && rm files_to_copy
Mit Bash getestet.
quelle
-exec
option oder using zu verwendenxargs
. So etwas wie:find LaTeX/ -type f -iname "*.pdf" -print0 | xargs -0 -i rsync -avn {} Output/
standalone
eine.tex
Datei mit demselben Namen ist oder nicht , da dies Bilder sind, die in einem Dokument enthalten sind ...--files-from
akzeptiert das Lesen von stdin. Dies würde funktionierenfind LaTeX/ -type f -a -iname "*.pdf" | rsync -avn --files-from=- ~/ ~/Output/
Nach dem Abschnitt "INCLUDE / EXCLUDE PATTERN RULES" auf der Manpage zu urteilen, ist dies der richtige Weg
Der entscheidende Unterschied zwischen dieser und der Antwort von kbrd ist das
--include="*/"
Flag, das rsync anweist, alle gefundenen Verzeichnisse zu kopieren, unabhängig von ihrem Namen. Dies ist erforderlich, da rsync nicht in ein Unterverzeichnis zurückkehrt, es sei denn, es wurde angewiesen, dieses Unterverzeichnis zu kopieren.Beachten Sie auch, dass die Anführungszeichen verhindern, dass die Shell versucht, die Muster zu Dateinamen relativ zum aktuellen Verzeichnis zu erweitern, und eine der folgenden Aktionen ausführt:
Erfolgreicher und durcheinander bringender Filter (nicht allzu wahrscheinlich in der Mitte einer solchen Flagge, obwohl Sie wirklich nie wissen, wann jemand eine Datei mit dem Namen
--include=foo.pdf
... erstellt)Wenn dies fehlschlägt und möglicherweise ein Fehler auftritt, anstatt den Befehl auszuführen (wie Sie es bei zsh standardmäßig festgestellt haben).
quelle
include
ändert es nichts , wenn zusätzliches Zeug bereits darin ist. Wenn Sie sehen, was ich meine ...--exclude="*"
nach dem--include="*.pdf"
, sonst wird alles übertragen.Wie wäre es damit:
quelle
man rsync
setzt den Filter hinter die Optionen und vor die Quelle / Ziele. Ich habe es versucht und es hat nicht funktionierta
Option ist für die Archivierung und unter anderem macht es das Kopieren rekursiv.Hier ist etwas, das funktionieren sollte, ohne find zu verwenden. Der Unterschied zu bereits geposteten Antworten ist die Reihenfolge der Filterregeln. Filterregeln in einem rsync-Befehl funktionieren ähnlich wie iptable-Regeln. Die erste Regel, mit der eine Datei übereinstimmt, wird verwendet. Von der Manualseite :
Daher benötigen Sie einen Befehl wie folgt:
Beachten Sie das Muster "**. Pdf". Nach der Manpage :
In meinem kleinen Test funktioniert dies rekursiv im Verzeichnisbaum und wählt nur die PDFs aus.
quelle
*.pdf
in das oberste Verzeichnis kopiert werden (aber nicht~/LaTeX/foo/bar.pdf
).**
. Wäre schön ein Beispiel dafür zu haben. ;)Dies ist meine bevorzugte Lösung:
Der
find
Befehl ist einfacher zu verstehen als die Einschluss- / Ausschlussregeln vonrsync
:-)Wenn Sie nur PDF-Dateien kopieren möchten, wechseln Sie einfach
.jpg
zu.pdf
quelle