GNU/Linux >> LINUX-Kenntnisse >  >> Linux

rsync mit Regex, um nur einige Dateien einzuschließen

Ich würde vorschlagen, die Filteroption von rsync zu verwenden. Geben Sie für Ihr Beispiel einfach Folgendes ein:

rsync -vam -f'+ *[Nn][Aa][Mm][E]*' -f'+ */' -f'- *' a b

Die erste Filterregel teilt rsync mit, welche Muster enthalten sein sollen. Die zweite Regel wird benötigt, um rsync anzuweisen, alle Verzeichnisse beim Durchlaufen zu überprüfen. Um zu verhindern, dass leere Verzeichnisse eingeschlossen werden, werden sie explizit durch -m ausgeschlossen Möglichkeit. Die letzte Filterregel weist rsync an, alle verbleibenden Muster zu entfernen, die bisher noch nicht übereinstimmten.


rsync spricht keine Regex. Sie können find und grep einsetzen, obwohl es ein wenig geheimnisvoll wird. So finden Sie die Zieldateien:

find a/ |
grep -i 'name'

Aber sie haben alle das Präfix "a/" - was Sinn macht, aber was wir am Ende haben wollen, ist eine Liste von Include-Mustern, die für rsync akzeptabel sind, und da das Präfix "a/" für rsync nicht funktioniert, habe ich' Ich werde es mit cut entfernen:

find . |
grep -i 'name' |
cut -d / -f 2-

Es gibt immer noch ein Problem - wir werden immer noch Dateien in Unterverzeichnissen vermissen, weil rsync keine Verzeichnisse in der Ausschlussliste durchsucht. Ich werde awk verwenden, um die Unterverzeichnisse aller übereinstimmenden Dateien zur Liste der Include-Muster hinzuzufügen:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'

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 auf der Standardeingabe bereitzustellen. Also insgesamt:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

Beachten Sie, dass auf das Quellverzeichnis „a“ über zwei verschiedene Pfade verwiesen wird – „a/“ und „./a/“. Das ist subtil, aber wichtig. Um die Dinge konsistenter zu machen, werde ich eine letzte Änderung vornehmen und auf das Quellverzeichnis immer als "./a/" verweisen. Dies bedeutet jedoch, dass der cut-Befehl geändert werden muss, da ein zusätzliches „./“ am Anfang der Ergebnisse von find:

steht
find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

Wenn Sie ZSH verwenden, können Sie das Flag (#i) verwenden, um die Groß-/Kleinschreibung zu deaktivieren. Beispiel:

$ touch NAME
$ ls (#i)*name*
NAME

ZSH unterstützt auch Ausschlüsse, die genau wie der reguläre Pfad angegeben werden, aber ein ~

am Anfang haben
$ touch aa ab ac
$ ls *~*c
aa ab

Sie können Ausschlüsse verketten:

$ ls *~*c~*b
aa

Schließlich können Sie angeben, welche Art von Datei Sie zurückgeben möchten (Verzeichnis, Datei usw.). Dies geschieht mit (/) für Verzeichnis und (.) für Datei.

$ touch file
$ mkdir dir
$ ls *(.)
file

Basierend auf all dem würde ich diesen Befehl wie folgt ausführen:

rsync -avvz *(/) (#i)*name* ./a/ ./b/

(Ich sehe bei diesen Selektoren keinen Bedarf für einen Ausschluss)


Linux
  1. Wie benenne ich viele Dateien mit Regex um?

  2. Nur übertragene Dateien mit Rsync protokollieren?

  3. Wie kann man Rsync selektiv stumm schalten?

  4. So senden und laden Sie Dateien mit Rsync herunter

  5. 6 rsync-Beispiele zum Ausschließen mehrerer Dateien und Verzeichnisse mit Exclude-From

Setzen Sie teilweise übertragene Dateien über SSH mit Rsync fort

So sichern Sie Dateien und Verzeichnisse mit Rsync unter Linux

Übertragen Sie Dateien mit WinSCP

Wie kann ich mit ls nur nicht leere Dateien auflisten?

rsync N neueste Dateien in einem Verzeichnis

SCP überträgt nur modifizierte Dateien