¿Cómo cambio el nombre de la extensión para un montón de archivos?
-
22-07-2019 - |
Pregunta
En un directorio, tengo un montón de archivos * .html
. Me gustaría cambiarles el nombre a * .txt
¿Cómo puedo hacer eso? Yo uso el bash shell.
Solución
Para una mejor solución (con solo la funcionalidad bash, a diferencia de las llamadas externas), consulte one de las otras respuestas .
Lo siguiente haría y no requiere que el sistema tenga el programa rename
(aunque lo más frecuente es que tenga esto en un sistema):
for file in *.html; do
mv "$file" "$(basename "$file" .html).txt"
done
EDITAR: Como se señaló en los comentarios, esto no funciona para los nombres de archivo con espacios en ellos sin las comillas adecuadas (ahora agregadas anteriormente). Cuando trabaje exclusivamente en sus propios archivos que sabe que no tienen espacios en los nombres de archivos, esto funcionará, pero siempre que escriba algo que pueda reutilizarse más adelante, no omita las comillas adecuadas.
Otros consejos
Si usa bash, no hay necesidad de comandos externos como sed, basename, rename, expr, etc.
for file in *.html
do
mv "$file" "${file%.html}.txt"
done
rename 's/\.html$/\.txt/' *.html
hace exactamente lo que quieres.
Esto funcionó para mí en OSX desde .txt a .txt_bak
find . -name '*.txt' -exec sh -c 'mv "<*>" "${0%.txt}.txt_bak"' {} \;
Desea utilizar rename
:
rename -S .html .txt *.html
Esto hace exactamente lo que desea: cambiará la extensión de .html
a .txt
para todos los archivos que coincidan con * .html
.
Nota: Greg Hewgill señala correctamente que esto no es un bash incorporado; y es un comando separado de Linux. Si solo necesita algo en Linux, esto debería funcionar bien; si necesita algo más multiplataforma, eche un vistazo a una de las otras respuestas.
En una Mac ...
- Instale rename si no tiene:
cambiar nombre de instalación -
renombrar -S .html .txt * .html
Para usuarios de Ubuntu:
rename 's/\.html$/\.txt/' *.html
Aquí hay un ejemplo del comando renombrar:
rename -n ’s/\.htm$/\.html/’ *.htm
El -n significa que es una prueba de funcionamiento y que en realidad no cambiará ningún archivo. Le mostrará una lista de archivos que cambiarían de nombre si eliminara -n. En el caso anterior, convertirá todos los archivos en el directorio actual de una extensión de archivo de .htm a .html.
Si el resultado de la ejecución de prueba anterior se veía bien, entonces podría ejecutar la versión final:
rename -v ’s/\.htm$/\.html/’ *.htm
El -v es opcional, pero es una buena idea incluirlo porque es el único registro que tendrá de los cambios que realizó el comando renombrar como se muestra en la salida de muestra a continuación:
$ 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 parte difícil en el medio es una sustitución de Perl con expresiones regulares, resaltada a continuación:
<*>Después del rastreo del sitio web de otra persona, terminé con miles de archivos sin la extensión .html, en un amplio árbol de subdirectorios.
Para cambiarles el nombre a todos de una vez, excepto los archivos que ya tienen una extensión .html (la mayoría de ellos no tenían ninguno), esto funcionó para mí:
cd wwwroot
find . -xtype f \! -iname *.html -exec mv -iv "{}" "{}.html" \; # batch rename files to append .html suffix IF MISSING
En el caso del OP, podría modificarlo ligeramente, solo para cambiar el nombre de los archivos * .txt, así:
find . -xtype f -iname *.txt -exec filename="{}" mv -iv ${filename%.*}.{txt,html} \;
Desglosado (¡hammertime!):
-iname * .txt
- Significa considerar SOLO archivos que ya terminan en .txt
mv -iv " {}. {txt, html} "
- Cuando find pasa un {} como nombre de archivo, $ {filename%. *} Extrae su nombre base sin ninguna extensión para formar los parámetros a mv . bash toma el {txt, html} para reescribirlo como dos parámetros para que el comando final se ejecute como: mv -iv " filename.txt " " filename.html "
Corrección necesaria: tratar con espacios en los nombres de archivo
Esta pregunta menciona explícitamente a Bash, pero si tiene ZSH disponible, es bastante simple:
zmv '(*).*' '$1.txt'
Si obtiene zsh: comando no encontrado: zmv
, simplemente ejecute:
autoload -U zmv
Y luego inténtalo de nuevo.
Gracias a este artículo original por el consejo acerca de zmv.
¡Esta es la solución más ingeniosa que he encontrado que funciona en OSX y Linux, y también funciona muy bien con git!
y con git:
El comando mmv
parece realizar esta tarea de manera muy eficiente en una gran cantidad de archivos (decenas de miles en un segundo). Por ejemplo, para cambiar el nombre de todos los archivos .xml
a .html
, use esto:
mmv ";*.xml" "#1#2.html"
el ;
coincidirá con la ruta, el *
coincidirá con el nombre del archivo, y estos se denominan # 1
y # 2
en el nombre de reemplazo.
respuestas basadas en exec
o las canalizaciones eran demasiado lentas o fallaban en una gran cantidad de archivos.
Prueba esto
rename .html .txt *.html
uso:
rename [find] [replace_with] [criteria]
Un poco tarde para la fiesta. Podrías hacerlo con xargs:
ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}
O si todos sus archivos están en alguna carpeta
ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}
Si prefiere PERL, hay un script PERL corto (escrito originalmente por Larry Wall, el creador de PERL) que hará exactamente lo que quiere aquí: tips.webdesign10.com/files/rename.pl.txt . Para su ejemplo, lo siguiente debería hacer el truco
rename.pl 's / html / txt /' * .html
=)
(Gracias @loretoparisi por la URL actualizada)
Lamentablemente, no es trivial hacerlo de forma portátil. Probablemente necesites un poco de magia expr.
for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done
Elimina el eco una vez que estés feliz de que haga lo que quieras.
Editar: basename
es probablemente un poco más legible para este caso particular, aunque expr
es más flexible en general.
Esta es una buena manera de modificar múltiples extensiones a la vez:
for fname in *.{mp4,avi}
do
mv -v "$fname" "${fname%.???}.mkv"
done
Nota: tenga cuidado de que el tamaño de la extensión sea el mismo (el ???)
Agradable & amp; ¡sencillo!
find . -iname *.html -exec mv {} "$(basename {} .html).text" \;
Esto es lo que solía cambiar el nombre de los archivos .edge
a .blade.php
for file in *.edge; do mv "$file" "$(basename "$file" .edge).blade.php"; done
Funciona como encanto.
Una línea, sin bucles:
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$