So kopieren Sie alle HTML-Dateien aus einem Verzeichnisbaum in ein einzelnes Verzeichnis


7

Ich möchte alle .htmlDateien aus myDirund ihre Unterverzeichnisse nach kopieren ~/otherDir. Folgendes habe ich versucht, aber es funktioniert nicht:

$ find myDir -name *.html -print | xargs -0 cp ~/otherDir
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
       cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory

Antworten:


3

find myDir -name '*.html' -print0 | xargs -0 -J % cp % ~/otherdir


1
-J ist nicht in gnu xargs (4.4.2)
simpatico

@simpatico: Es handelt sich um eine BSD-Erweiterung, mit der mehrere Elemente übergeben werden können, auch wenn nachfolgende Argumente vorliegen. Es gibt kein GNU-Äquivalent AFAIK.
Gilles 'SO - hör auf böse zu sein'

12

Zuallererst ist die Shell das '*' für Sie. Entkomme es entweder mit \oder benutze Anführungszeichen*.html

Wie so:

find myDir -name "*.html" oder find myDir -name \*.html

Überspringen Sie die Verwendung von xargsmit find's -execSchalter:

find myDir -name "*.html" -exec cp {} ~/otherDir \;

Dies funktioniert, weil es {}den Platz der gefundenen Datei einnimmt findund für jede Übereinstimmung einmal ausgeführt wird.

Beachten Sie auch, dass dadurch die Kopie des Quellverzeichnisses reduziert wird. Beispiel:

myDir/a.html
myDir/b/c.html

wird nachgeben

otherdir/a.html
otherdir/c.html

Auf dem Mac habe ich nicht -t, sondern $ find MR -name "* .html" -exec cp ~ / debug {} \; Drucke: "cp: / Users / simpatico / debug ist ein Verzeichnis (nicht kopiert)." für jede HTML-Datei
Simpatico

Oh, das hast du in deiner Frage nicht erwähnt. Es wäre wahrscheinlich für andere hilfreich, wenn Sie Ihre Frage mit "osx" markieren könnten. Sie können dies immer noch mit -exec tun - ich werde meine Antwort bearbeiten.
Miles Strombach

Schlimmer noch, es wird auch kopieren beide mydir/a/a.htmlund mydir/b/a.htmlauf otherdir/a.htmlund es ist nicht ganz offensichtlich vorhersehbar was man windet sich über letzte kopiert, das ist wahrscheinlich nicht etwas , was Sie wollen ...
Shadur

1
@simpatico, du hast die Bestellung falsch verstanden. Es ist -exec cp {} ~/debug/ \;nicht -exec cp ~/debug {} \;aus den ziemlich offensichtlichen Gründen, wenn Sie darüber nachdenken ...
Shadur

4

Sie möchten also alle .htmlDateien in einem Quellverzeichnis und seinen Unterverzeichnissen in ein einziges Verzeichnis kopieren (dh die Hierarchie reduzieren)?

POSIX Standard:

find myDir -name '*.html' -type f -exec sh -c 'cp "$@" "$0"' ~/otherDir {} +

Beachten Sie, dass dies ~/otherDirParameter 0 für die Zwischenshell wird, wodurch die Quelldateien präzise sein können "$@". Das Belassen des Zielverzeichnisses außerhalb der Shell hat den zusätzlichen Vorteil, dass keine Anführungszeichen auftreten, wenn dies eine Variable im übergeordneten Shell-Skript ( -exec sh -c 'cp "$@" "$0"' "$target") ist.

Für ältere Systeme, die nicht haben find … -exec … +:

find myDir -name '*.html' -type f -exec cp {} ~/otherDir \;

I Ihre Shell ist Bash ≥4 oder zsh:

shopt -s globstar  # only for bash, put it in your `.bashrc`
cp myDir/**/*.html ~/otherDir/

setopt globstar funktioniert unter bash 4.2 nicht unter mac und linux.
Simpatico

@simpatico: Sorry, das ist shopt -s( setoptist der entsprechende Befehl in zsh).
Gilles 'SO - hör auf böse zu sein'

Wird nach nicht -type fausgewertet -name "*.html"? Während a.html ein gültiger Verzeichnisname ist, würde ich keinen erwarten. Vielleicht -type fwäre es sinnvoller, bevor Sie den Dateinamen überprüfen, aber ich denke, es gibt selten einen Unterschied in der Ausführungsgeschwindigkeit.
Benutzer unbekannt

2

Versuchen

find myDir -name '*.html' -exec cp -t ~/otherdir {} +

Ein Problem bei diesem Ansatz besteht darin, dass keine Unterverzeichnisse erstellt werden, sodass alle Dateien eingefügt werden ~/otherDir und Dateien mit demselben Namen, aber in verschiedenen Teilen des myDirBaums nicht kopiert werden.

Wenn dies zu einem Problem führen würde, können Sie Folgendes verwenden, um denselben Verzeichnisbaum innerhalb des ~/otherDirBaums zu erstellen

find myDir -name '*.html' | cpio -pdm ~/otherdir

Ich habe keinen Mac

find myDir -name '*.html' -print | xargs -I {} cp  {} ~/otherDir

oder wenn du kannst

find myDir -name '*.html' -print0 | xargs -0 -I {} cp  {} ~/otherDir

Dies ist sicher für Dateien mit Leerzeichen im Namen.


@lain - hast du bemerkt, dass mein Mac nur begrenzt ist? Ich habe eigentlich vor, die Struktur nicht zu kopieren, daher wäre cmd ideal, wenn es funktionieren würde, aber das Schreiben des cmd ohne -t reicht nicht aus (ich bekomme die Verwendung immer noch gedruckt).
Simpatico

In Mavericks gibt es (zumindest) keinen "-t" -Schaltbefehl "cp", es handelt sich also um eine GNU / Linux-Lösung.
Denis Barmenkov

@DenisBarmenkov Ich glaube, ich habe das ungefähr zur Hälfte meiner Antwort angesprochen.

2

Unterstützt OSX -execdir für find?

 find ./myDir -name "*.html" -execdir cp {} /abspath/to/otherDir ";"

Gnu / find schlägt in den meisten Fällen vor, -execdir anstelle von -exec zu verwenden.


Es tut . So auch alle (aktuell genug) BSDs. -execdirist besser für den Fall, dass ein Verzeichnis während des findBetriebs verschoben wird, aber leider nicht portierbar ist.
Gilles 'SO - hör auf böse zu sein'

0
ls myDir/*.html | xargs -I {} cp {} ~/otherDir

Dies ist nur eine triviale Variation der bereits gegebenen Antworten mit einigen Nachteilen. Beispielsweise werden nur Dateien in der obersten Ebene gefunden myDir, und in der Frage werden Dateien aus myDir und deren Unterverzeichnissen
Scott
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.