Wie können Sie alle Dateien eines bestimmten Typs in ein Verzeichnis in Unix verschieben (oder kopieren)?

22

Ich bin noch nicht mit allen Tricks vertraut grep/find/awk/xargs.

Ich habe einige Dateien, die einem bestimmten Muster entsprechen, zum Beispiel *.xxx. Diese Dateien befinden sich an zufälligen Orten in einem bestimmten Verzeichnis. Wie kann ich solche Dateien finden und in einen Ordner in meinem Home-Verzeichnis unter Unix verschieben (der möglicherweise noch nicht existiert)?

qodeninja
quelle
4
Sie müssen aufpassen, wenn Sie über "Dateityp" sprechen. In Unix-Umgebungen ist das Beispiel ".xxx" nicht einmal eine Erweiterung im Sinne von Windows. ".xxx" ist nur ein Suffix des Dateinamens. "Dateityp" ist eine von mehreren Kategorien: reguläre Datei, Gerätedatei, symbolische Verknüpfung, Verzeichnis, Named Pipe, Socket der Unix-Familie, möglicherweise einige andere.
Bruce Ediger
@ BruceEdiger danke, ich denke, ich meinte wirklich "Dateinamenmuster"
Qodeninja

Antworten:

22
mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;
Kevin
quelle
1
Ich würdemv -i -t ~/dst {} +
Enzotib
17

Wenn Sie alle Dateien innerhalb einer Verzeichnishierarchie in ein einzelnes Zielverzeichnis verschieben möchten, geben Sie in bash ≥4 ( shopt -s globstarin Ihr Verzeichnis ~/.bashrc) oder zsh Folgendes ein :

mkdir ~/new-directory
mv -i **/*.xxx ~/new-directory

In anderen Schalen:

mkdir ~/new-directory
find . -name '*.xxx' -exec mv -i {} ~/new-directory \;

So lesen Sie diesen findBefehl:

  • .: Durchsucht das aktuelle Verzeichnis
  • -name '*.xxx': Handle auf Dateien, deren Name mit diesem Muster übereinstimmt
  • -exec … \;: Führen Sie diesen Befehl für jede Datei aus und ersetzen Sie ihn {}durch den Pfad zur Datei

Die Verwendung eines komplexeren Befehls findist schneller, wenn Sie über viele Dateien verfügen, da nicht mvfür jede Datei ein separater Prozess aufgerufen werden muss:

find . -name '*.xxx' -exec sh -c 'mv -i "$@" "$0"' ~/new-directory {} +

Am +Ende wird angegeben find, dass der Befehl für mehrere Dateien gleichzeitig aufgerufen werden soll. Da finddie Dateinamen nur am Ende der Befehlszeile angegeben werden können und mvdas Zielverzeichnis das letzte sein muss, verwenden wir eine Zwischen-Shell, um die Argumente neu anzuordnen (dies "$0"ist das erste Argument für die Shell ~/new-directoryund "$@"die nachfolgenden Argumente von findErweiterung von {}).

Gilles 'SO - hör auf böse zu sein'
quelle
4

Wenn Sie die Verzeichnisstruktur der übereinstimmenden Quelldateien in das neue Zielverzeichnis replizieren möchten, können Sie die Option --parents von GNU cp verwenden :

mkdir /path/to/target_dir
cd source_dir
find . -name '*.xxx' -exec cp -iv --parents -t /path/to/target_dir {} +
frielp
quelle
3

Sie können ohne find verwenden -exec‍auch:

mkdir /path/to/dest    
cp `find /path/to/source -name "*.jar"` /path/to/dest
Ken Zein
quelle
1
Beachten Sie jedoch, dass dies find -execviel sicherer ist. Dies schlägt beispielsweise bei Dateinamen mit Leerzeichen fehl.
Dhag