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.
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:
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.
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
ren *.htm *.html
Funcionará en Windows.Respuestas:
O, puedes usar bash puro ... (excepto para mv, es decir ...)
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.
fuente
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.Aún mejor, para el caso especial de simplemente agregar al final:
fuente
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
fuente
rename
viene con perl, y básicamente cada unix viene con perl en estos días.shopt -s globstar
(desactivado por defecto). Además, Linux y Unix tienen directorios en lugar de carpetas.Pruébalo con un
echo
en frente demv
primera vezEl problema con tu original es que "
mv *.htm *.html
" tiene el*
s manejado por la concha, por lo que elmv
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.fuente
mv
no funcionaráSin embargo, otro ejemplo de bash puro utilizando la cadena de reemplazo.
Extra: reemplaza todas las ocurrencias de una cadena.
fuente
Si utiliza Zsh puedes usar 'zmv'
fuente
La mejor herramienta es mmv .
Otros ejemplos de uso (y de otras herramientas) en " Resumen de herramientas de línea de comandos de GNU / Linux ".
fuente
#
.los util-linux-ng paquete (en Fedora) tiene una
rename
comando similar al mencionado por TRS-80 . Puedes usarlo así:fuente