Comment déplacer (ou copier) tous les fichiers d'un certain type vers un répertoire sous Unix?

22

Je ne connais pas encore très bien toutes les astuces de grep/find/awk/xargs.

J'ai des fichiers correspondant à un modèle particulier, par exemple *.xxx. Ces fichiers se trouvent à des emplacements aléatoires dans un certain répertoire. Comment puis-je trouver tous ces fichiers et les déplacer dans un dossier de mon répertoire personnel sous Unix (qui n'existe peut-être pas encore)?

qodeninja
la source
4
Vous devez faire attention lorsque vous parlez de "type de fichier". Dans les environnements unixy, l'exemple ".xxx" n'est même pas une extension au sens de Windows. ".xxx" constitue juste un suffixe du nom de fichier. Le "type de fichier" est plutôt l'une des quelques catégories: fichier ordinaire, fichier de périphérique, lien symbolique, répertoire, canal nommé, socket de la famille Unix, peut-être quelques autres.
Bruce Ediger
@BruceEdiger merci, je suppose que je voulais vraiment dire "modèle de nom de fichier"
qodeninja

Réponses:

22
mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;
Kevin
la source
1
J'utiliseraismv -i -t ~/dst {} +
enzotib
17

Si vous souhaitez déplacer tous les fichiers d'une hiérarchie de répertoires vers un répertoire de destination unique, en bash ≥4 (insérez shopt -s globstarvotre ~/.bashrc) ou zsh:

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

Dans d'autres coquilles:

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

Comment lire cette findcommande:

  • .: parcourir le répertoire courant
  • -name '*.xxx': agir sur les fichiers dont le nom correspond à ce modèle
  • -exec … \;: exécuter cette commande sur chaque fichier, en remplaçant {}par le chemin d'accès au fichier

Il existe une commande plus complexe findqui est plus rapide si vous avez de nombreux fichiers car elle n'a pas besoin d'appeler un mvprocessus distinct pour chaque fichier:

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

Le +à la fin indique findd'appeler la commande sur plusieurs fichiers à la fois. Puisque findne peut mettre les noms de fichiers qu'à la fin de la ligne de commande et mvdoit avoir le répertoire de destination en dernier, nous utilisons un shell intermédiaire pour réorganiser les arguments ( "$0"est le premier argument du shell ~/new-directory, et "$@"sont les arguments suivants provenant de findexpansion de {}).

Gilles 'SO- arrête d'être méchant'
la source
4

Si vous souhaitez répliquer la structure de répertoires des fichiers source correspondants dans le nouveau répertoire cible, vous pouvez utiliser l' option --parents de GNU cp :

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

vous pouvez utiliser sans trouver -exec‍aussi bien:

mkdir /path/to/dest    
cp `find /path/to/source -name "*.jar"` /path/to/dest
Ken Zein
la source
1
Notez cependant que find -execc'est beaucoup plus sûr; ce qui précède échouera sur les noms de fichiers contenant des espaces blancs, par exemple.
dhag