Renombra un grupo de archivos con un comando

38

Si tengo un grupo de archivos con una extensión .htm, ¿cómo puedo cambiarles el nombre a .html?

mv *.htm *.html

No funciona.

Richard Hoskins
fuente
Sólo por el bien de la integridad, ren *.htm *.html Funcionará en Windows.
Brian Burns

Respuestas:

50

O, puedes usar bash puro ... (excepto para mv, es decir ...)

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

y evitar las cosas desagradables nombre bajo. ;)

Bash tiene un extenso conjunto de opciones de expansión variable. El que se usa aquí, '%', elimina el sufijo más pequeño del valor de la variable. El patrón es un patrón glob, por lo que ${file%.*} También funcionaría. El operador '%%' elimina el mayor sufijo coincidente, y es intercambiable en el ejemplo anterior, ya que el patrón es fijo, ${file%%.*}.html sin embargo, convertiría a.b.htm en a.html.

Vea la sección de sustitución de variables de la página de manual de bash para más trucos ingeniosos. Hay mucho que se puede hacer dentro de bash directamente.

falstro
fuente
1
También tenga en cuenta que estas expansiones de parámetros no se limitan a golpetazo . Están disponibles en todas las conchas derivadas de Bourne ( sh , ksh , golpetazo , zsh , guión , ceniza , etc.). Las expansiones son parte de. La especificación POSIX para el "Lenguaje de Comando de Shell" y son altamente portátiles.
Chris Johnsen
11

No debe haber espacios, nuevas líneas u otros espacios en blanco en los nombres de archivo, pero esta versión de la respuesta de freiheit los maneja. Tambien usa $() En lugar de backticks para facilitar la lectura junto con otros beneficios.

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

Aún mejor, para el caso especial de simplemente agregar al final:

for file in *.htm
do
    mv "$file" "${file}l"
done
Dennis Williamson
fuente
11

rename(1) Es una utilidad de Perl que hace exactamente lo que quieres. En este caso:

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

o si está utilizando subdirectorios también

(requiere Bash 4.0 y la configuración de globstar: shopt -s globstar )

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

TRS-80
fuente
1
cambiar el nombre es más fácil, pero no es un programa estándar de Unix; La pregunta original no especifica que unix. Parece ser "prename" en algunos lugares.
freiheit
2
rename viene con perl, y básicamente cada unix viene con perl en estos días.
TRS-80
3
Sí, pero no todos los Unix incluyen programas auxiliares como 'renombrar' cuando ponen perl en el sistema. OSX, por ejemplo, no tiene "cambio de nombre".
freiheit
1
@William: la sintaxis de doble asterisco solo está disponible en Bash 4 en adelante y solo si está activada con shopt -s globstar (desactivado por defecto). Además, Linux y Unix tienen directorios en lugar de carpetas.
Dennis Williamson
6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

Pruébalo con un echo en frente de mv primera vez

El problema con tu original es que " mv *.htm *.html " tiene el * s manejado por la concha, por lo que el mv el comando simplemente ve una lista de todos los archivos .htm y .html en el directorio actual. En otras palabras, algo como " mv foo.htm bar.htm stuff.htm six.htm file.htm ". mv solo sabe cómo manejar más de 2 argumentos si el último es un directorio.

freiheit
fuente
1
Debes citar "$ file", para manejar los espacios.
Richard Hoskins
Su descripción del problema original debe ser enfatizada más fuertemente. Este comportamiento de expansión de comodines de shell es sorprendente y no intuitivo para alguien que viene de Windows Land, y entender lo que hace el shell deja en claro por qué la aplicación original de mv no funcionará
Greg Hewgill
3

Sin embargo, otro ejemplo de bash puro utilizando la cadena de reemplazo.

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

Extra: reemplaza todas las ocurrencias de una cadena.

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

La mejor herramienta es mmv .

mmv \*.htm #1.html

Otros ejemplos de uso (y de otras herramientas) en " Resumen de herramientas de línea de comandos de GNU / Linux ".

bortzmeyer
fuente
1
Tu ejemplo de uso falla. Necesitas escapar #.
Cristian Ciupitu
No, funciona (SIEMPRE prueba antes de publicar en SuperUser). La necesidad de escapar # depende de la shell que uses (yo uso zsh).
bortzmeyer
0

los util-linux-ng paquete (en Fedora) tiene una rename comando similar al mencionado por TRS-80 . Puedes usarlo así:

rename .htm .html *.html
Cristian Ciupitu
fuente