Ich versuche, rsync auszuführen, um einige Dateien rekursiv in einen Pfad zu kopieren, basierend auf ihrem Dateinamenmuster, wobei die Groß- und Kleinschreibung nicht berücksichtigt wird . Folgendes habe ich getan, um rsync auszuführen:
$ rsync -avvz --include ='*/' --include='.*[Nn][Aa][Mm][E].*' --exclude='*' ./a/ ./b/
Nichts wird kopiert, die Debug-Ausgabe zeigt:
[sender] hiding file 1Name.txt because of pattern *
[sender] hiding file 1.txt because of pattern *
[sender] hiding file 2.txt because of pattern *
[sender] hiding file Name1.txt because of pattern *
[sender] hiding directory test1 because of pattern *
[sender] hiding file NaMe.txt because of pattern *
Ich habe versucht,: --include='*[Nn][Aa][Mm][E]*'
und andere Kombinationen zu verwenden, aber es geht immer noch nicht.
Irgendwelche Ideen, wie man Regex verwendet, um einige Dateien einzuschließen?
--exclude='*'
?Antworten:
rsync spricht keinen regulären Ausdruck. Sie können find und grep eintragen, obwohl es ein wenig arkan wird. So finden Sie die Zieldateien:
Aber sie haben alle das Präfix "a /" - was Sinn macht, aber am Ende möchten wir eine Liste von Include-Mustern haben, die für rsync akzeptabel sind, und da das Präfix "a /" für rsync I nicht funktioniert ' ll entfernen Sie es mit Schnitt:
Es gibt immer noch ein Problem - wir werden immer noch Dateien in Unterverzeichnissen vermissen, da rsync keine Verzeichnisse in der Ausschlussliste durchsucht. Ich werde awk verwenden, um die Unterverzeichnisse aller übereinstimmenden Dateien zur Liste der Include-Muster hinzuzufügen:
Alles, was übrig bleibt, ist, die Liste an rsync zu senden - wir können das Argument --include-from = - verwenden, um eine Liste von Mustern für rsync bei Standardeingabe bereitzustellen. Also insgesamt:
Beachten Sie, dass auf das Quellverzeichnis 'a' über zwei verschiedene Pfade verwiesen wird - "a /" und "./a/". Das ist subtil, aber wichtig. Um die Konsistenz zu verbessern, werde ich eine letzte Änderung vornehmen und das Quellverzeichnis immer als "./a/" bezeichnen. Dies bedeutet jedoch, dass der Befehl cut geändert werden muss, da auf der Vorderseite der Ergebnisse von find ein zusätzliches "./" angezeigt wird:
quelle
-t
dass dies ein gültiger Schalter ist.sed "s#^$1/*##"
B .: Buuuut, das auf Pfaden mit einem # unterbrochen wird. Um das zu beheben, müssen wir den Namen des eingehenden Verzeichnisses zitieren:prefix=$(echo "$1" | sed 's#/#\\/#g')
und dann sindsed "s/^$prefix\\/*//"
die Unterabschnitte des Bash-Zitierens ein Albtraum;)Ich würde vorschlagen, die Filteroption von rsync zu verwenden. Geben Sie für Ihr Beispiel einfach Folgendes ein:
Die erste Filterregel teilt rsync mit, welche Muster eingeschlossen werden sollen. Die zweite Regel wird benötigt, um rsync anzuweisen, alle Verzeichnisse auf seiner Durchquerung zu überprüfen. Um zu verhindern, dass leere Verzeichnisse aufgenommen werden, werden sie
-m
optional explizit ausgeschlossen . Die letzte Filterregel weist rsync an, alle verbleibenden Muster zu entsorgen, die bisher noch nicht übereinstimmen.quelle
Wenn Sie ZSH verwenden, können Sie mit dem Flag (#i) die Groß- und Kleinschreibung deaktivieren. Beispiel:
ZSH unterstützt auch Ausschlüsse, die genau wie der reguläre Pfad angegeben werden, aber ein initiales ~ haben
Sie können Ausschlüsse verketten:
Schließlich können Sie angeben, welche Art von Datei zurückgegeben werden soll (Verzeichnis, Datei usw.). Dies geschieht mit (/) für Verzeichnis und (.) Für Datei.
Basierend auf all dem würde ich diesen Befehl wie folgt ausführen:
(Ich sehe keine Notwendigkeit für einen Ausschluss mit diesen Selektoren)
quelle
Die Antwort von @ sqweek oben ist fantastisch, obwohl ich vermute, dass er einen Fehler in seinem
awk
Skript zum Generieren von übergeordneten Verzeichnissen hat, da er mir z.Ich konnte es beheben, indem ich
gensub
stattdessen Folgendes verwendete:Seine vollständige Lösung mit dem
awk
geänderten Bit wäre also:quelle
sub("/[^/]*$")
) zu verankern .Versucht mit einem C # -Skript, da dies die Sprache ist, mit der ich am meisten Erfahrung habe. Ich kann die Liste der Dateien erstellen, die ich einschließen möchte, aber jemand von rsync sagt mir immer noch, dass ich eine Wanderung machen soll. Es erstellt die Ordner, ignoriert jedoch die Dateien. Hier ist was ich habe ..
Zuerst der Inhalt des Verzeichnisses:
Dann die Ausgabe des C # -Skripts:
Und die Debug-Ausgabe:
quelle
[EDIT] Dies funktioniert nur lokal. Bei Remote-Pfaden muss zuerst die Verzeichnisstruktur erstellt werden.
Einfacher als die akzeptierte Antwort; Verwenden Sie --file-from, das automatisch übergeordnete Verzeichnisse enthält, und drucken Sie den Dateipfad mit% P.
Sie müssen also nur
find
und verwendenrsync
.quelle