web-dev-qa-db-fra.com

Comment renommer l'extension d'un lot de fichiers?

Dans un répertoire, j'ai un tas de fichiers *.html.

J'aimerais les renommer tous en *.txt

J'utilise le bash Shell.

413
bmw0128

Pour une meilleure solution (avec uniquement la fonctionnalité bash, par opposition aux appels externes), voir une des autres réponses .


Ce qui suit ferait et n'exigerait pas que le système ait le programme rename (bien que vous l'ayez le plus souvent sur un système):

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

EDIT: Comme indiqué dans les commentaires, cela ne fonctionne pas pour les noms de fichiers contenant des espaces sans citation correcte (maintenant ajouté ci-dessus). Lorsque vous travaillez uniquement sur vos propres fichiers et que vous savez qu'il n'y a pas d'espaces dans les noms de fichiers, cela fonctionnera, mais si vous écrivez quelque chose qui peut être réutilisé ultérieurement, ne sautez pas la citation correcte. 

329
Mikael Auno

Si vous utilisez bash, vous n'avez pas besoin de commandes externes telles que sed, basename, renommer, expr, etc.

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done
594
ghostdog74
rename 's/\.html$/\.txt/' *.html

fait exactement ce que vous voulez.

176
Amber

Vous voulez utiliser rename :

rename -S .html .txt *.html

Cela fait exactement ce que vous voulez - cela changera l'extension de .html à .txt pour tous les fichiers correspondant à *.html.

Remarque: Greg Hewgill souligne à juste titre qu'il ne s'agit pas d'une bash intégrée. et est une commande Linux séparée. Si vous avez juste besoin de quelque chose sur Linux, cela devrait fonctionner correctement; Si vous avez besoin de quelque chose de plus multi-plateforme, jetez un coup d'œil à l'une des autres réponses.

85
DaveR

Cela a fonctionné pour moi sur OSX de .txt à .txt_bak

find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;
84
Steven Lizarazo

Sur un Mac ...

  1. Installer renommer si vous n’avez pas: brew install rename
  2. rename -S .html .txt *.html
32
izilotti

Pour les utilisateurs Ubuntu: 

rename 's/\.html$/\.txt/' *.html
15
Bheru Lal Lohar

Voici un exemple de la commande renommer:

rename -n ’s/\.htm$/\.html/’ *.htm

Le -n signifie qu'il s'agit d'un test et ne modifiera aucun fichier. Il vous montrera une liste de fichiers qui seraient renommés si vous supprimiez le -n. Dans le cas ci-dessus, tous les fichiers du répertoire en cours seront convertis à partir d'une extension de fichier de .htm à .html.

Si le résultat du test ci-dessus semble correct, vous pouvez exécuter la version finale:

rename -v ’s/\.htm$/\.html/’ *.htm

L'option -v est facultative, mais il est judicieux de l'inclure car il s'agit du seul enregistrement des modifications apportées par la commande rename, comme illustré dans l'exemple de sortie ci-dessous:

$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html

La partie délicate au milieu est une substitution Perl avec des expressions régulières, soulignée ci-dessous:

rename -v ’s/\.htm$/\.html/’ *.htm
7
A.A

Cette question mentionne explicitement Bash, mais si vous avez ZSH disponible, c'est assez simple:

zmv '(*).*' '$1.txt'

Si vous obtenez zsh: command not found: zmv, lancez simplement:

autoload -U zmv

Et puis réessayez.

Merci à cet article article original pour l'astuce sur zmv.

5
Michael Leonard

C'est la solution la plus simple que j'ai trouvée qui fonctionne sous OSX et Linux, et elle fonctionne également avec git!

find . -name "*.js" -exec bash -c 'mv "$1" "${1%.js}".tsx' - '{}' \;

et avec git:

find . -name "*.js" -exec bash -c 'git mv "$1" "${1%.js}".tsx' - '{}' \;

5
bdombro

Après l'exploration du site Web de quelqu'un d'autre, des milliers de fichiers portant l'extension .html manquant, à travers une vaste arborescence de sous-répertoires, me manquaient.

Les renommer tous en une fois, à l'exception des fichiers ayant déjà une extension .html (la plupart n'en avaient aucune), cela fonctionnait pour moi:

cd wwwroot
find . -xtype f \! -iname *.html   -exec mv -iv "{}"  "{}.html"  \;  # batch rename files to append .html suffix IF MISSING

Dans le cas du PO, je pourrais le modifier légèrement pour ne renommer que les fichiers * .txt, comme suit:

find . -xtype f  -iname *.txt   -exec filename="{}"  mv -iv ${filename%.*}.{txt,html}  \; 

En panne (hammertime!):

-iname * .txt
- Signifie que SEUL les fichiers se terminant déjà par .txt

mv -iv "{}. {txt, html}" - Lorsque find passe un {} comme nom de fichier, $ {filename%. *} Extrait son nom de base sans extension pour former les paramètres à mv . bash prend le {txt, html} pour le réécrire sous forme de deux paramètres de sorte que la dernière commande s'exécute comme suit: mv -iv "filename.txt" "filename.html"

Correction nécessaire cependant: traiter les espaces dans les noms de fichiers

5
Marcos

La commande mmv semble effectuer cette tâche de manière très efficace sur un très grand nombre de fichiers (des dizaines de milliers en une seconde). Par exemple, pour renommer tous les fichiers .xml en .html, utilisez ceci: 

mmv ";*.xml" "#1#2.html"

le ; correspondra au chemin, le * correspondra au nom de fichier, et ces noms sont appelés #1 et #2 dans le nom de remplacement 

Les réponses basées sur exec ou les pipes étaient soit trop lents, soit échouaient sur un très grand nombre de fichiers. 

4
Roko Mijic

Un peu tard pour la fête. Vous pouvez le faire avec xargs:

ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}

Ou si tous vos fichiers sont dans un dossier

ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}
3
esp

Essaye ça

rename .html .txt *.html 

usage: 

rename [find] [replace_with] [criteria]
3
P Sreedhar

Si vous préférez Perl, il existe un court script Perl (écrit à l'origine par Larry Wall, le créateur de Perl) qui fera exactement ce que vous voulez ici: tips.webdesign10.com/files/rename.pl.txt . Pour votre exemple, ce qui suit devrait faire l'affaire

rename.pl 's/html/txt/' *.html

=)

(Merci @loretoparisi pour l'URL mise à jour)

2
dudusan

C'est un bon moyen de modifier plusieurs extensions à la fois:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

Remarque: faites attention à la taille de l'extension pour qu'elle soit la même (la ???)

1
Nick De Greek

Nice & simple!

find . -iname *.html  -exec mv {} "$(basename {} .html).text"  \;
1
Deano

Voici ce que j’ai utilisé pour renommer les fichiers .Edge en .blade.php

for file in *.Edge; do     mv "$file" "$(basename "$file" .Edge).blade.php"; done

Fonctionne comme un charme.

0
Nixon Kosgei

Malheureusement, ce n'est pas anodin à faire de manière portable. Vous avez probablement besoin d'un peu de magie expr.

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

Supprimez l'écho une fois que vous êtes heureux, il fait ce que vous voulez.

Edit: basename est probablement un peu plus lisible pour ce cas particulier, bien que expr soit plus flexible en général.

0
CB Bailey

Vous pouvez également créer une fonction dans Bash, l'ajouter à .bashrc ou à un autre objet, puis l'utiliser où vous le souhaitez.

change-ext() {
    for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}

Usage:

change-ext css scss

Source du code dans la fonction: https://stackoverflow.com/a/1224786/6732111

0
J Kluseczka

Une ligne, pas de boucles: ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}

cbongiorno@ip-172-31-26-242:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json  ac8453e2-0d82-4d43-b80e-205edb754700.json
cbongiorno@ip-172-31-26-242:~/pgsql$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
cbongiorno@ip-172-31-26-242:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt  ac8453e2-0d82-4d43-b80e-205edb754700.txt
cbongiorno@ip-172-31-26-242:~/pgsql$ 
0