Renommer un groupe de fichiers avec une seule commande

38

Si j'ai un groupe de fichiers avec une extension .htm, comment puis-je les renommer tous en .html?

mv *.htm *.html

ne marche pas.

Richard Hoskins
la source
Juste pour être complet, ren *.htm *.htmlfonctionnera sous Windows.
Brian Burns

Réponses:

50

Ou, vous pouvez utiliser pure bash ... (sauf pour mv, c'est-à-dire ..)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

et évitez les trucs méchants de base. ;)

Bash dispose d'un vaste ensemble d'options d'extension variables. Celui utilisé ici, '%', supprime le plus petit suffixe correspondant de la valeur de la variable. Le motif est un motif glob, donc ${file%.*}fonctionnerait aussi. L'opérateur '%%' supprime le suffixe de correspondance le plus grand, et est interchangeable dans l'exemple ci-dessus, car le motif est fixé, ${file%%.*}.htmlabhtm deviendrait cependant un fichier a.html.

Reportez-vous à la section relative à la substitution variable de la page de manuel bash pour obtenir des astuces plus judicieuses. Il y a beaucoup de choses qui peuvent être faites directement au sein de bash.

falstro
la source
1
Notez également que ces extensions de paramètres ne se limitent pas à bash . Ils sont disponibles sur tous les shells dérivés de Bourne ( sh , ksh , bash , zsh , dash , cendres , etc.). Les extensions font partie de la spécification POSIX pour le «langage de commande shell» et sont très portables.
Chris Johnsen
11

Il ne devrait pas y avoir d'espaces, de nouvelles lignes ou d'autres espaces dans les noms de fichiers, mais cette version de la réponse de freiheit les gère. Il utilise également $()au lieu de backticks pour la lisibilité avec d'autres avantages.

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

Encore mieux - pour le cas particulier de simplement ajouter à la fin:

for file in *.htm
do
    mv "$file" "${file}l"
done
En pause jusqu'à nouvel ordre.
la source
11

rename(1)est un utilitaire Perl qui fait exactement ce que vous voulez. Dans ce cas:

rename 's/\.htm$/.html/' *htm

ou si vous utilisez des sous-répertoires aussi

(nécessite Bash 4.0 et le réglage de globstar: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm

TRS-80
la source
1
renommer est plus facile, mais ce n’est pas un programme unix standard; La question originale ne précise pas quel unix. Semble être "prename" dans certains endroits.
Freiheit
2
renamevient avec perl, et fondamentalement chaque unix vient avec perl ces jours-ci.
TRS-80
3
oui, mais tous les unix ne comprennent pas des programmes auxiliaires tels que 'renommer' quand ils mettent perl sur le système. OSX, par exemple, n'a pas "renommer" dessus.
Freiheit
1
@William: la syntaxe double astérisque n'est disponible que dans Bash 4 et versions ultérieures et uniquement si elle est activée avec shopt -s globstar(désactivé par défaut). En outre, Linux et Unix ont des répertoires plutôt que des dossiers.
pause jusqu'à nouvel ordre.
6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

Essayez-le avec un echodevant la mvpremière fois.

Le problème avec votre original est que " mv *.htm *.html" le *s est géré par le shell. La mvcommande voit donc simplement une liste de tous les fichiers .htm et .html du répertoire en cours. En d'autres termes, quelque chose comme " mv foo.htm bar.htm stuff.htm six.htm file.htm". mv ne sait gérer plus de 2 arguments que si le dernier est un répertoire.

freiheit
la source
1
Vous devriez citer "$ file", pour gérer les espaces.
Richard Hoskins
Votre description du problème initial devrait être soulignée plus fortement. Ce comportement d’extension de shell pour les caractères génériques est surprenant et n’intéresse pas les utilisateurs de Windows, mais comprendre son fonctionnement montre clairement pourquoi l’application originale mvne fonctionnera pas.
Greg Hewgill le
3

Encore un autre exemple pur bash utilisant string replace.

for file in *.htm; do mv $file ${file/htm/html}; done

Extra - remplace toutes les occurrences d'une chaîne

for file in *.htm; do mv $file ${file//htm/html}; done
xalupadas
la source
1

Si vous utilisez Zsh, vous pouvez utiliser 'zmv'

Martin
la source
1

Le meilleur outil est mmv .

mmv \*.htm #1.html

Autres exemples d'utilisation (et d'autres outils) dans " Résumé des outils de ligne de commande GNU / Linux ".

Bortzmeyer
la source
1
Votre exemple d'utilisation échoue. Vous devez vous échapper #.
Cristian Ciupitu
Non, ça marche (je teste TOUJOURS avant de poster sur SuperUser). La nécessité de s'échapper dépend du shell que vous utilisez (j'utilise zsh).
Bortzmeyer
0

Le paquet util-linux-ng (sur Fedora) a une renamecommande similaire à celle mentionnée par TRS-80 . Vous pouvez l'utiliser comme ceci:

rename .htm .html *.html
Cristian Ciupitu
la source