Kopieren Sie einen bestimmten Dateityp, wobei Sie die Ordnerstruktur beibehalten.
On Februar 10, 2021 by adminIch habe eine Ordnerstruktur mit einer Reihe von * .csv-Dateien, die über die Ordner verteilt sind. Jetzt möchte ich alle * .csv-Dateien unter Beibehaltung der Ordnerstruktur an ein anderes Ziel kopieren.
Dies funktioniert folgendermaßen:
cp --parents *.csv /target cp --parents */*.csv" /target cp --parents */*/*.csv /target cp --parents */*/*/*.csv /target ...
und usw., aber ich würde es gerne mit einem Befehl tun.
Antwort
find
hat eine sehr praktische -exec
Option:
find . -name "*.csv" -exec cp --parents \{\} /target \;
Kommentare
- Wahrscheinlich aus diesem Grund \ {\} \;
-
'{}'
funktioniert genauso gut - Obwohl
-execdir
ist sicherer als-exec
. Durch einfaches Ersetzen wird die Ordnerstruktur nicht wie beabsichtigt erhalten. - Warum ich Nachricht abrufen ‚ Auslassen des Verzeichnisses ‚, wenn ich versuche, sie mit Ihrem Befehl zu kopieren?
- Können Sie erklären, warum das Klammern müssen hier maskiert werden?
Antwort
Sie können auch rsync
für this.
$ rsync -a --prune-empty-dirs --include "*/" --include "*.csv" --exclude "*" source/ target/
Wenn Sie leere Verzeichnisse aus dem Quellbaum behalten möchten, überspringen Sie die Option --prune-empty-dirs
:
$ rsync -a --include "*/" --include "*.csv" --exclude "*" source/ target/
Wenn Sie nicht möchten, dass Symlinks, Änderungsdaten, Dateiberechtigungen, Eigentümer usw. erhalten bleiben, ersetzen Sie bitte -a
mit einer anderen Kombination von -rlptgoD
. 😉
Kommentare
-
-m
ist eine Verknüpfung für--prune-emty-dirs
. - Außerdem kann die Option
-R
hinzugefügt werden, um die übergeordnete Verzeichnisstruktur der Quelle zu kopieren. (vgl. meine Antwort hier.) - -R funktioniert bei mir! Danke
Antwort
Sie können find und cpio im Durchgangsmodus
find . -name "*.csv" | cpio -pdm /target
Hier werden alle CSV-Dateien gefunden im aktuellen Verzeichnis und darunter und kopieren Sie sie nach / target, wobei Sie die in .
verwurzelte Verzeichnisstruktur beibehalten.
Wenn Sie
Es findet die gesamte Datei in /path/to/files
und darunter und kopiert sie nach /target/path/to/files
und darunter
Kommentare
- Ich habe alle Antworten von oben bis unten ausprobiert, und dies war die einzige, die beim ersten Versuch funktioniert hat
- Dies sollte die akzeptierte Antwort sein.
- Ich fand die GNU-Dokumente hilfreich: “ Im Copy-Pass-Modus [angefordert von der Option
-p
, cpio] liest die Liste der zu kopierenden Dateien von der Standardeingabe. Das Verzeichnis, in das sie kopiert werden, wird als Argument ohne Option angegeben. “ … “ -d Erstellen Sie bei Bedarf führende Verzeichnisse. “ … “ -m Behalten Sie die Änderungszeiten früherer Dateien bei beim Erstellen von Dateien. “
Antwort
Der Befehl cp
erlaubt mehrere Quellargumente:
cp **/*.csv --parents ../target
CAVEAT: Ich verwende hier einen rekursiven Glob; dies ist die Option globstar
in Bash 4+ und ksh
und wird standardmäßig in zsh
unterstützt. Rekursive Globs tun nicht stimmen mit versteckten Dateien und Ordnern überein, und Einige Implementierungen folgen Symlinks, andere nicht .
Wenn Ihre Shell dies nicht tut. “ t supp oder rekursive Globs, oder wenn Sie sie lieber nicht verwenden möchten, können Sie Folgendes tun:
-
*.csv */*.csv */*/*.csv */*/*/*.csv
– das ist natürlich sehr redundant und erfordert das Wissen, wie tief Ihre Verzeichnisstruktur ist. -
$(find . -name "*.csv")
– Diese wird stimmen mit versteckten Dateien und Ordnern überein.find
unterstützt auch die Angabe, ob Symlinks befolgt werden, was nützlich sein kann.
Kommentare
- das ist genau das, was ich versucht habe (der rekursive Glob) und es hat einige, aber nicht alle gefunden? ziemlich komisch. Ich habe genau das gleiche Ergebnis erhalten, wenn ich das Skript npm copyfiles verwende, aber wenn ich den Befehl find verwende, findet es alles …
- @Randyaa Ich ‚ brauche etwas Weitere Details darüber, welche Dateien genau ‚ nicht gefunden wurden, um Ihnen zu helfen. Möglicherweise finden Sie die Diskussion hier und die Fortsetzung hier über das genaue Verhalten des rekursiven Globs hilfreich
- stellt sich heraus, dass rekursiver Glob aus irgendeinem Grund nicht ‚ nicht aktiviert wurde …Ich ‚ bin noch nie darauf gestoßen, aber ich habe es mit nur einer Ausführung von
shopt -s globstar
unmittelbar vor meinem Befehl korrigiert und alles ist in Ordnung. Vielen Dank für das Follow-up! -
--parents
war das, wonach ich gesucht habe. danke
Antwort
Dieser hat bei mir funktioniert:
find -name "*.csv" | xargs cp --parents -t /target
Kommentare
- Beste Antwort mit einfachster Syntax. Funktioniert einwandfrei und ist leicht zu merken. In vielen Fällen ist
find [things] | xargs [do stuff]
sehr leistungsfähig. - Einverstanden. Im Vergleich zu einigen anderen Antworten sehr einfach.
- Unterbrechungen, wenn Leerzeichen in Dateinamen vorhanden sind
- @MichelePiccolini Leerzeichen in Dateinamen können mit
find -print0
undxargs -0
.
Antwort
Von rsync
„Manpage:
-R, –relative
Verwenden Sie relative Pfade. Dies bedeutet, dass die in der Befehlszeile angegebenen vollständigen Pfadnamen an den Server gesendet werden und nicht nur die letzten Teile der Dateinamen. Dies ist besonders nützlich, wenn Sie mehrere verschiedene Verzeichnisse gleichzeitig senden möchten Dieser Befehl:
rsync -av /foo/bar/baz.c remote:/tmp/
… dies würde eine Datei mit dem Namen baz.c in / tmp / auf dem Remotecomputer erstellen. Wenn Sie stattdessen p verwenden würden >
rsync -avR /foo/bar/baz.c remote:/tmp/
Dann wird eine Datei mit dem Namen /tmp/foo/bar/baz.c auf dem Remotecomputer erstellt, wobei der vollständige Pfad beibehalten wird. Diese zusätzlichen Pfadelemente werden als “ impli ed Verzeichnisse „(d.h. die Verzeichnisse „foo“ und „foo / bar“ im obigen Beispiel).
Das würde also auch funktionieren:
rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
Kommentare
- Vielen Dank, dass Sie diese Antwort gegeben haben. Kompatibel mit BSD Userland (macOS) -, – und -Pfaden mit Leerzeichen.
Antwort
Angenommen, Sie möchten diese Struktur von ./source
nach ./destination
replizieren:
cd source find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)
Ich bin bereit, dies als eine Zeile zu zählen, wobei cd source
eine eingebaute Shell ist.
Kommentare
-
tar
verfügt über die Option-C
, um zu vermeiden, dass das Verzeichnis zuerst geändert werden muss.
Schreibe einen Kommentar