web-dev-qa-db-fra.com

Comment déplacer des fichiers en fonction du premier mot dans le nom de fichier?

Dans un dossier, j'ai des milliers de fichiers, tels que:

cat eats mouse.jpg
cat chases mouse.jpg
gorilla eats banana.jpg
gorilla is sleeping.jpg
elephant is huge.jpg
elephant has trunk.jpg
(and so on...)

Je veux un script bash qui déplacera ces fichiers en fonction du premier mot du nom de fichier (chat, gorille, éléphant, etc.) dans des dossiers, également créés en fonction du premier mot, de sorte que:

  • Le dossier 'cat' est créé et tous les fichiers commençant par 'cat' sont déplacés dans ce dossier.
  • Le dossier 'gorilla' est créé et tous les fichiers commençant par 'gorilla' sont déplacés dans ce dossier.
  • Le dossier 'elephant' est créé et tous les fichiers commençant par elephant sont déplacés dans ce dossier.
  • (Etc..)
1
user163125

L'oneliner suivant devrait faire le travail:

find . -maxdepth 1 -type f -name '*.jpg' -exec Perl -e '$a="{}"; $a =~ /(\w+)/; `mkdir -p $1 && mv "$a" $1`' \;

Explication

  • find . -maxdepth 1 -type f -name '*.jpg' Recherchera les fichiers (-type f) Uniquement dans le dossier actuel (. -maxdepth 1) Avec l'extension jpg.

  • -exec Appellera la commande Perl pour chaque fichier correspondant. La chaîne {} Est remplacée par le nom de fichier en cours de traitement.

  • $a="{}"; Enregistre le fichier actuel

  • $a =~ /(\w+)/ est un test d'expression régulière, la variable spéciale $1 contiendra le premier mot du nom de fichier stocké dans $a.

  • enfin mkdir -p $1 && mv "$a" $1 est exécuté comme une commande système avec /bin/sh ou son équivalent. Notez l'option -p De mkdir, elle n'échouera pas si le répertoire existe déjà.

enter image description here


Mise à jour

Pour empêcher l'injection de code en Perl (merci @ geirha ), utilisez la fonction quotemeta comme suit:

find . -maxdepth 1 -type f -name '*.jpg' -exec Perl -e '$a="\Q@ARGV"; $a =~ /(\w+)/; `mkdir -p $1 && mv $a $1`' "{}" \;
7
Sylvain Pineau

J'utiliserais une boucle for pour cela.

for file in ./*" "*.jpg; do
    Word=${file%% *}
    mkdir -p "$Word" &&
    mv "$file" "$Word"
done

Vous pouvez l'exécuter dans un shell interactif ou le mettre dans un script. Bash est très utile à connaître, donc je recommande de l'apprendre en lisant le Bash Guide quand vous avez le temps.

3
geirha