Wie kann ich nur eine bestimmte Liste von Dateien rsync?

93

Ich habe ungefähr 50 Dateien in verschiedenen Unterverzeichnissen, die ich auf einen Remote-Server übertragen möchte. Ich dachte, rsync könnte dies mit der Option --include-from für mich tun. Ohne die Option --exclude = "*" werden alle Dateien im Verzeichnis synchronisiert, mit der Option sind keine Dateien vorhanden.

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ [email protected]:/var/www/ --dry-run

Ich führe es zunächst als trocken aus und 0.0.0.0 wird offensichtlich durch die IP des Remote-Servers ersetzt. Der Inhalt von rsync_include.txt ist eine neue zeilengetrennte Liste relativer Pfade zu den Dateien, die ich hochladen möchte.

Gibt es einen besseren Weg, der mir an einem Montagmorgen entgeht?

Dan Steele
quelle

Antworten:

3

Edit: Josip Rodins Antwort unten ist besser. Bitte benutzen Sie diesen!

Wenn Sie nach einer bestimmten Liste von Dateien suchen und diese stattdessen direkt in die Befehlszeile einfügen, fällt es Ihnen möglicherweise leichter:

# rsync -avP -e ssh `cat deploy/rsync_include.txt` [email protected]:/var/www/

Dies setzt jedoch rsync_include.txtvoraus , dass Ihre Liste nicht so lang ist, dass die Befehlszeilenlänge ein Problem darstellt und dass die Datei nur echte Pfade enthält (dh keine Kommentare und keine regulären Ausdrücke).

Wes Hardaker
quelle
9
Leider funktioniert dies nicht mit einer großen Liste oder mit Dateien mit Leerzeichen im Namen.
Wes Modes
2
[Argumentliste zu lang]
Dankó Dávid
Standardmäßig hängt xargs Argumente von stdin an das Ende der Befehlszeile an. Das funktioniert nicht, da rsync das letzte Argument benötigt, um das Ziel zu sein. Einige Versionen von xargs können stattdessen optional Argumente in die Mitte der Befehlszeile einfügen. Das sollte funktionieren, solange es Ihnen nichts ausmacht, dass rsync mehr als einmal ausgeführt wird, wenn die Liste der Dateien lang ist. In jedem Fall ist das rsync --files-fromwahrscheinlich eine einfachere und zuverlässigere Lösung :)
Lassi
Wes Hardaker: Bezieht sich Ihre Bearbeitung und Ihr Verweis auf "Josip Rodins Antwort" tatsächlich auf die @ atp-Antwort , die Rodin bearbeitet hat?
Seamus
226

Es gibt eine Flagge --files-from, die genau das tut, was Sie wollen. Von man rsync:

--files-from=FILE

Mit dieser Option können Sie die genaue Liste der zu übertragenden Dateien angeben (wie aus der angegebenen DATEI gelesen oder - für die Standardeingabe). Außerdem wird das Standardverhalten von rsync optimiert, um die Übertragung nur der angegebenen Dateien und Verzeichnisse zu vereinfachen:

  • Die Option --relative (-R) ist impliziert, wodurch die Pfadinformationen erhalten bleiben, die für jedes Element in der Datei angegeben sind (verwenden Sie --no-relative oder --no-R, wenn Sie dies deaktivieren möchten).

  • Die Option --dirs (-d) ist impliziert, wodurch Verzeichnisse erstellt werden, die in der Liste am Ziel angegeben sind, anstatt sie geräuschvoll zu überspringen (verwenden Sie --no-dirs oder --no-d, wenn Sie dies deaktivieren möchten).

  • Das Verhalten der Option --archive (-a) impliziert nicht --recursive (-r). Geben Sie es daher explizit an, wenn Sie dies wünschen.

  • Diese Nebenwirkungen ändern den Standardstatus von rsync, sodass die Position der Option --files-from in der Befehlszeile keinen Einfluss darauf hat, wie andere Optionen analysiert werden (z. B. -a funktioniert vor oder nach --files- gleich). von, wie --no-R und alle anderen Optionen).

Die Dateinamen, die aus der DATEI gelesen werden, beziehen sich alle auf das Quellverzeichnis. Alle führenden Schrägstriche werden entfernt und es dürfen keine ".." - Referenzen höher als das Quellverzeichnis sein. Nehmen Sie zum Beispiel diesen Befehl:

rsync -a --files-from=/tmp/foo /usr remote:/backup

Wenn / tmp / foo die Zeichenfolge "bin" (oder sogar "/ bin") enthält, wird das Verzeichnis / usr / bin als / backup / bin auf dem Remote-Host erstellt. Wenn es "bin /" enthält (beachten Sie den abschließenden Schrägstrich), wird auch der unmittelbare Inhalt des Verzeichnisses gesendet (ohne dass dies in der Datei explizit erwähnt werden muss - dies begann in Version 2.6.4). In beiden Fällen würde, wenn die Option -r aktiviert wäre, auch die gesamte Hierarchie dieses Verzeichnisses übertragen (beachten Sie, dass -r explizit mit --files-from angegeben werden muss, da dies nicht durch -a impliziert wird). Beachten Sie auch, dass die (standardmäßig aktivierte) Option --relative nur die Pfadinformationen dupliziert, die aus der Datei gelesen werden - die Duplizierung des Quellspezifikationspfads (in diesem Fall / usr) nicht erzwingt. .

Darüber hinaus kann die Datei --files-from vom Remote-Host anstelle des lokalen Hosts gelesen werden, wenn Sie vor der Datei ein "host:" angeben (der Host muss mit einem Ende der Übertragung übereinstimmen). Als Abkürzung können Sie nur das Präfix ":" angeben, um "das entfernte Ende der Übertragung verwenden" zu bedeuten. Beispielsweise:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

Dies würde alle Dateien kopieren, die in der Datei / path / file-list angegeben sind, die sich auf dem Remote-Host "src" befindet.

Wenn die Optionen --iconv und --protect-args angegeben sind und die Dateinamen --files-from von einem Host zu einem anderen gesendet werden, werden die Dateinamen vom Zeichensatz des sendenden Hosts in den Zeichensatz des empfangenden Hosts übersetzt.

ANMERKUNG: Durch das Sortieren der Liste der Dateien in der Eingabe --files-from wird rsync effizienter, da die Pfadelemente, die von benachbarten Einträgen gemeinsam genutzt werden, nicht erneut aufgerufen werden. Wenn die Eingabe nicht sortiert ist, werden einige Pfadelemente (implizite Verzeichnisse) möglicherweise mehrmals gescannt, und rsync macht sie schließlich rückgängig, nachdem sie in Dateilistenelemente umgewandelt wurden.

atp
quelle
22
Beachten Sie, dass Sie immer noch das Verzeichnis angeben müssen, in dem sich die aufgelisteten Dateien befinden, zum Beispiel: rsync -av --files-from=file-list . target/um Dateien aus dem aktuellen Verzeichnis zu kopieren.
Nicolas Mattia
7
Ja, und um es noch einmal zu wiederholen : The filenames that are read from the FILE are all relative to the source dir.
Am
Ah, das habe ich verpasst, sorry!
Nicolas Mattia
1
Wenn die Datei-aus-Datei etwas hat, das mit ..rsync beginnt, scheint dies zu ignorieren .., wenn ich einen Fehler wie rsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory(in diesem Fall aus dem Verzeichnis "test" ausführen und versuchen, "../subdir/test.txt" anzugeben, das vorhanden ist.
Michael
Kann das --files-fromArgument mit einer expliziten Liste von Einschlüssen und --files-fromAusschlüssen kombiniert werden, und werden die hinzugefügten Dateien aus der Liste mit überschriebenen Ausschlussregeln überschrieben, sodass sie eingeschlossen werden, wenn sie in der Datei erscheinen?
Highsciguy
12

--files-from=Der Parameter benötigt einen abschließenden Schrägstrich, wenn der absolute Pfad intakt bleiben soll. Ihr Befehl würde also wie folgt aussehen:

rsync -av --files-from=/path/to/file / /tmp/

Dies kann so geschehen, als ob es eine große Anzahl von Dateien gibt und Sie alle Dateien in den x-Pfad kopieren möchten. Sie würden also die Dateien finden und die Ausgabe in eine Datei wie die folgende werfen:

find /var/* -name *.log > file
Waqas Khan
quelle
8

Für die Aufzeichnung half keine der obigen Antworten außer einer. Zusammenfassend können Sie den Sicherungsvorgang folgendermaßen ausführen --files-from=:

 rsync -aSvuc `cat rsync-src-files` / mnt / d / rsync_test /

ODER

rsync -aSvuc --recursive --files-from = rsync-src-files. / mnt / d / rsync_test /

Der erstere Befehl ist neben dem Inhalt der Datei, auf rsync-src-filesdie ich weiter unten näher eingehen werde, selbsterklärend . Wenn Sie nun die letztere Version verwenden möchten, müssen Sie die folgenden vier Anmerkungen beachten:

  1. Hinweis braucht man sowohl zu spezifizieren --files-fromund das Quellverzeichnis
  2. Man muss explizit spezifizieren --recursive.
  3. Die Datei rsync-src-filesist eine vom Benutzer erstellte Datei und wurde für diesen Test im Verzeichnis src abgelegt
  4. Sie rsyn-src-filesenthalten die zu kopierenden Dateien und Ordner und werden relativ zum Quellverzeichnis erstellt. WICHTIG: Stellen Sie sicher, dass die Datei keine nachgestellten Leerzeichen oder Leerzeilen enthält. Im folgenden Beispiel gibt es nur zwei Zeilen, nicht drei (zufällig herausfinden). Inhalt von rsynch-src-filesist:

Ordnername1
Ordnername2

KF
quelle
3

Ich habe eine ähnliche Aufgabe: alle nach dem angegebenen Datum geänderten Dateien rsync, aber einige Verzeichnisse ausgenommen. Es war schwierig, einen All-in-One-Liner zu bauen, deshalb habe ich das Problem in kleinere Teile zerlegt. Endgültige Lösung:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

Zuerst benutze ich find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". Ich habe versucht, eine Zeile hinzuzufügen regex, findum Namensmuster auszuschließen, aber mein Geschmack von Linux (Mint) -Nähten, Negativ-Regex nicht zu verstehen find. Versuchte Anzahl von Regex-Aromen - funktioniert nicht wie gewünscht. Am Ende habe ich egrep -valso eine Option, die das Muster auf einfache Weise ausschließt. My rsynckopiert keine Verzeichnisse wie /.cache oder /.config sowie einige andere, die ich explizit benannt habe.

sopel
quelle
1
Ich glaube, Sie könnten die Prozessersetzung verwenden, um daraus einen bashrsync -v --files-from=<(find ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | grep -Ev "/\..|Downloads|FOO") ~/sourceDIR /Destination
Einzeiler zu machen
2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

Syntax: rsync <file_/_folder_list> <source> <target>

Ordnernamen (hier MIT einem Trailing /; zB Cancer - Evolution/) befinden sich in einer Ordnerlistendatei (zB: cm_folder_list_test):

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

Wenn Sie diese /nachfolgenden nicht einschließen , werden die rsync-Zielordner erstellt, sind jedoch leer.

Diese Ordnernamen werden an den Rest ihres Pfads ( /home/victoria/Mail/2_RESEARCH - NEWS) angehängt , wodurch der vollständige Ordnerpfad für rsync bereitgestellt wird. zB : /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/.

Beachten Sie, dass Sie auch --files-from=..., NICHT --include-from=... verwenden müssen.

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(In meinem BASH-Skript habe ich die Variable $INwie folgt definiert .)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

Verwendete rsync-Optionen:

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (/server/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...
Victoria Stuart
quelle
1

Diese Antwort ist nicht die direkte Antwort auf die Frage. Aber es sollte Ihnen helfen, herauszufinden, welche Lösung am besten zu Ihrem Problem passt.

Bei der Analyse des Problems sollten Sie die Debug-Option aktivieren -vv

Dann gibt rsync aus, welche Dateien von welchem ​​Muster eingeschlossen oder ausgeschlossen werden:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *
Matthias M.
quelle
0

Keine dieser Antworten funktionierte für mich, als ich nur eine Liste von Verzeichnissen hatte . Dann bin ich auf die Lösung gestoßen! Sie müssen hinzufügen -r, --files-fromda -adies in diesem Szenario nicht rekursiv ist (wer wusste das?!).

rsync -aruRP --files-from=directory.list . ../new/location
Theodore R. Smith
quelle
Wenn Sie "dir" in der Datei auflisten, müssen Sie -r / —recursive angeben. Wenn Sie "dir /" auflisten, tun Sie dies nicht.
lbutlr