Je veux renommer plusieurs fichiers (file1 … fileN to file1_renamed … fileN_renamed) en utilisant find
commande :
find . -type f -name 'file*' -exec mv filename='{}' $(basename $filename)_renamed ';'
Mais obtenir cette erreur :
mv: cannot stat ‘filename=./file1’: No such file or directory
Cela ne fonctionne pas car le nom de fichier n'est pas interprété comme une variable shell.
Réponse acceptée :
Voici une solution directe de votre approche :
find . -type f -name 'file*' -exec sh -c 'x="{}"; mv "$x" "${x}_renamed"' \;
Cependant, cela coûte très cher si vous avez beaucoup de fichiers correspondants, car vous démarrez un nouveau shell (qui exécute un mv
) pour chaque match. Et si vous avez des personnages amusants dans n'importe quel nom de fichier, cela explosera. Voici une approche plus efficace et sécurisée :
find . -type f -name 'file*' -print0 | xargs --null -I{} mv {} {}_renamed
Il a également l'avantage de travailler avec des fichiers aux noms étranges. Si find
le supporte, cela peut être réduit à
find . -type f -name 'file*' -exec mv {} {}_renamed \;
Les xargs
version est utile lorsque vous n'utilisez pas {}
, comme dans
find .... -print0 | xargs --null rm
Ici rm
est appelé une fois (ou plusieurs fois avec de nombreux fichiers), mais pas pour tous les fichiers.
J'ai supprimé le basename
dans votre question, car c'est probablement faux :vous déplaceriez foo/bar/file8
vers file8_renamed
, pas foo/bar/file8_renamed
.
Modifications (comme suggéré dans les commentaires) :
- Ajout d'un raccourci
find
sansxargs
- Autocollant de sécurité ajouté