Kopieren Sie alle Dateien mit einer bestimmten Erweiterung aus allen Unterverzeichnissen

110

Unter Unix möchte ich alle Dateien mit einer bestimmten Erweiterung (alle Excel-Dateien) aus allen Unterverzeichnissen in ein anderes Verzeichnis kopieren. Ich habe den folgenden Befehl:

cp --parents `find -name \*.xls*` /target_directory/

Die Probleme mit diesem Befehl sind:

  • Es kopiert auch die Verzeichnisstruktur und ich möchte nur die Dateien (daher sollten alle Dateien in / target_directory / landen).

  • Es werden keine Dateien mit Leerzeichen in den Dateinamen kopiert (die ziemlich viele sind).

Irgendwelche Lösungen für diese Probleme?

Abdel
quelle
Was ist mit find... exec mv?
Fedorqui 'SO hör auf,'

Antworten:

172

--parents kopiert die Verzeichnisstruktur, also sollten Sie das loswerden.

Die Art und Weise, wie Sie dies geschrieben haben, wird findausgeführt und die Ausgabe wird in die Befehlszeile eingefügt, sodass cpnicht zwischen den Leerzeichen zwischen den Dateinamen und den Leerzeichen innerhalb des Dateinamens unterschieden werden kann. Es ist besser so etwas zu tun

$ find . -name \*.xls -exec cp {} newDir \;

in dem cpfür jeden gefundenen Dateinamen ausgeführt findund der Dateiname korrekt übergeben wird. Hier finden Sie weitere Informationen zu dieser Technik.

Anstelle all der oben genannten können Sie zsh verwenden und einfach eingeben

$ cp **/*.xls target_directory

zsh kann Platzhalter um Unterverzeichnisse erweitern und macht solche Dinge sehr einfach.

Brian Agnew
quelle
2
Ja. 'bin it' bedeutet, es wegzuwerfen. Jetzt geändert :-)
Brian Agnew
12
Bash4.0+ und ksh93unterstützt auch **. Verwenden shopt -s globstarSie für Bash, um es zu aktivieren. Für ksh ist es set -Goder set -o globstar.
Pynexj
2
@Daryl - Ich habe weiter ausgefüllt. Aber die Antwort wurde bereits als "akzeptiert" markiert, Anmerkung
Brian Agnew
4
Diese Ausführung ist technisch weniger effizient als die Übergabe an xargs, was alles in so wenigen CP-Aufrufen wie möglich find . -name '*.xls' -print0 | xargs -0 cp -t destdir
erledigt
1
@Taywee - ja. Ich wollte die Dinge jedoch nicht verwirren und mich einfach auf das jeweilige Thema konzentrieren. Eine weitere Effizienzmaßnahme ist immer gut
Brian Agnew
35

Aus all dem habe ich mir diese Version ausgedacht. Diese Version funktioniert auch für mich im Mac Recovery Terminal.

find ./ -name '*.xsl' -exec cp -prv '{}' '/path/to/targetDir/' ';'

Es wird im aktuellen Verzeichnis und rekursiv in allen Unterverzeichnissen nach Dateien mit der Erweiterung xsl gesucht. Sie werden alle in das Zielverzeichnis kopiert.

CP-Flags sind:

  • p - Attribute der Datei beibehalten
  • r - rekursiv
  • v - ausführlich (zeigt Ihnen, was kopiert wird)
Guya
quelle
1
Dies ist das gleiche wie das, was ich tun musste, als SSH in Bluehost einstieg.
Plummer
4
Es werden KEINE Unterverzeichnisse gespeichert.
b005t3r
3
@ b005t3r das ist beabsichtigt, soll es nicht. Das war die ganze Absicht der OP-Frage. Er wollte, dass alle Dateien aus Unterverzeichnissen in ein Verzeichnis ohne Unterverzeichnisse kopiert wurden
Madivad
1
Gibt es eine Möglichkeit, dies zu ändern, um Unterverzeichnisse beizubehalten?
Matthew Dean
8

Ich hatte ein ähnliches Problem. Ich habe es gelöst mit:

find dir_name '*.mp3' -exec cp -vuni '{}' "../dest_dir" ";"

Das '{}'und ";"führt die Kopie für jede Datei aus.

stingMantis
quelle
3

Ich musste das auch selbst machen. Ich habe es über das Argument --parents für cp gemacht:

find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;
Dieser Typ
quelle
1
find [SOURCEPATH] -type f -name '[PATTERN]' | 
    while read P; do cp --parents "$P" [DEST]; done

Sie können die --parents entfernen, es besteht jedoch die Gefahr einer Kollision, wenn mehrere Dateien denselben Namen tragen.

Camion
quelle