¿Cómo cambio el nombre de la extensión de un lote de archivos?

En un directorio, tengo un montón de archivos *.html .

Me gustaría cambiarles el nombre a todos *.txt

Yo uso el shell bash.

Para una mejor solución (con solo funcionalidad bash, a diferencia de las llamadas externas), vea una de las otras respuestas .


Lo siguiente haría y no requiere que el sistema tenga el progtwig de 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ñala en los comentarios, esto no funciona para los nombres de archivos con espacios en ellos sin las citas correctas (ahora agregado anteriormente). Cuando trabaje exclusivamente en sus propios archivos que sepa que no tienen espacios en los nombres de los archivos, esto funcionará, pero cada vez que escriba algo que pueda volver a usarse en otro momento, no omita las citas correctas.

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

Desea utilizar el rename :

 rename -S .html .txt *.html 

Esto hace exactamente lo que quiere: 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 basil incorporado; y es un comando separado de Linux. Si solo necesitas algo en Linux, esto debería funcionar bien; si necesita algo más multiplataforma, eche un vistazo a una de las otras respuestas.

Esto funcionó para mí en OSX de .txt a .txt_bak

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

En una Mac …

  1. Instalar rename si no lo has hecho: brew install rename
  2. rename -S .html .txt *.html

Para usuarios de Ubuntu:

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

Aquí hay un ejemplo del comando de cambio de nombre:

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

-N significa que es una ejecución de prueba y no cambiará realmente ningún archivo. Le mostrará una lista de archivos que se cambiarían de nombre si eliminaba la opción -n. En el caso anterior, convertirá todos los archivos en el directorio actual desde una extensión de archivo de .htm a .html.

Si la salida 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 realizados por el comando de cambio de nombre como se muestra en el resultado de la 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 Perl con expresiones regulares, que se destaca a continuación:

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

Después del rastreo del sitio web de otra persona, terminé con miles de archivos que carecían de la extensión .html, en un amplio árbol de subdirectorios.

Para renombrarlos 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 SOLAMENTE archivos que ya terminan en .txt

mv -iv “{}. {txt, html}” – Cuando find pasa a {} como nombre de archivo, $ {filename%. *} extrae su nombre de 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"

Sin embargo, era necesario corregir: tratar con espacios en nombres de archivo

Prueba esto

 rename .html .txt *.html 

uso:

 rename [find] [replace_with] [criteria] 

Un poco tarde para la fiesta. Puedes hacerlo con xargs:

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

O si todos tus archivos están en alguna carpeta

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

Esta pregunta menciona explícitamente Bash, pero si tienes ZSH disponible es bastante simple:

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

Si obtiene zsh: command not found: zmv , simplemente ejecute:

 autoload -U zmv 

Y luego intenta de nuevo.

Gracias a este artículo original por el consejo sobre zmv.

El comando mmv parece hacer 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 archivos .html , use esto:

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

el ; coincidirá con la ruta, el * coincidirá con el nombre del archivo, y estos se conocen como #1 y #2 en el nombre de reemplazo.

Las respuestas basadas en exec o pipes fueron demasiado lentas o fallaron en una gran cantidad de archivos.

Si prefiere PERL, existe un breve script PERL (originalmente escrito por Larry Wall, el creador de PERL) que hará exactamente lo que quiera aquí: tips.webdesign10.com/files/rename.pl.txt . Para su ejemplo, lo siguiente debería ser el truco

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

=)

(Gracias @loretoparisi por la URL actualizada)

Lamentablemente, no es trivial hacerlo de manera 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 contento de que haga lo que quieras.

Editar: basename es probablemente un poco más legible para este caso en particular, aunque expr es más flexible en general.

.edge es lo que solía cambiar el .edge archivos .blade.php a .blade.php

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

Funciona como el encanto.

Intereting Posts