Tengo muchos archivos con .abc
extensión y quiero cambiarlos a .edefg
¿Cómo hacer esto desde la línea de comandos?
Tengo una carpeta raíz con muchas subcarpetas, por lo que la solución debería funcionar de forma recursiva.
command-line
bash
rename
batch-rename
tommyk
fuente
fuente
Respuestas:
Una forma portátil (que funcionará en cualquier sistema compatible con POSIX):
En bash4, puedes usar globstar para obtener globos recursivos (**):
El
rename
comando (perl) en Ubuntu puede cambiar el nombre de los archivos usando la sintaxis de expresión regular perl, que puede combinar con globstar ofind
:Ver también http://mywiki.wooledge.org/BashFAQ/030
fuente
"${1%.abc}"
se expande al valor de$1
excepto sin.abc
al final. Vea las preguntas frecuentes 100 para obtener más información sobre las manipulaciones de cadenas de shell${1%.abc}...
sh -c
el primer argumento se asigna a $ 0 y los argumentos restantes se asignan a los parámetros posicionales . Entonces el_
es un argumento ficticio, y '{}' es el primer argumento posicional parash -c
.Esto hará la tarea requerida si todos los archivos están en la misma carpeta
Para cambiar el nombre de los archivos de forma recursiva, use esto:
fuente
rename 's/.abc$/.edefg/' /path/to/root/folder/**/*.abc
en una versión moderna de Bash.s
al principio, y qué otras opciones puedo usar allí. Gracias !Un problema con los cambios de nombre recursivos es que cualquiera que sea el método que use para ubicar los archivos, pasa toda la ruta
rename
, no solo el nombre del archivo. Eso dificulta hacer cambios de nombre complejos en carpetas anidadas.Utilizo
find
la-execdir
acción para resolver este problema. Si utiliza en-execdir
lugar de-exec
, el comando especificado se ejecuta desde el subdirectorio que contiene el archivo coincidente. Entonces, en lugar de pasar todo el camino arename
, solo pasa./filename
. Eso hace que sea mucho más fácil escribir la expresión regular.En detalle:
-type f
significa solo buscar archivos, no directorios-name '*.abc'
significa que solo coinciden los nombres de archivo que terminan en .abc'{}'
es el marcador de posición que marca el lugar donde-execdir
se insertará la ruta encontrada. Las comillas simples son necesarias para permitirle manejar nombres de archivos con espacios y caracteres de shell.-type
y-name
son el carácter de continuación de línea bash. Los uso para hacer que este ejemplo sea más legible, pero no son necesarios si pones tu comando en una sola línea.-execdir
se requiere la barra diagonal inversa al final de la línea. Está ahí para escapar del punto y coma, que termina el comando ejecutado por-execdir
. ¡Divertido!Explicación de la expresión regular:
s/
inicio de la expresión regular\.\/
coincidir con los principales ./ que -execdir pasa. Use \ para escapar del. y / metacaracteres (nota: esta parte varía según su versión defind
. Vea el comentario del usuario @apollo)(.+)
coincide con el nombre del archivo. Los paréntesis capturan la coincidencia para su uso posterior.\.abc
escapar del punto, unir el abc$
anclar el partido al final de la cadena/
marca el final de la parte de "coincidencia" de la expresión regular, y el comienzo de la parte de "reemplazo"version1_
agregue este texto a cada nombre de archivo$1
hace referencia al nombre de archivo existente, porque lo capturamos con paréntesis. Si usa varios conjuntos de paréntesis en la parte de "coincidencia", puede consultarlos aquí usando $ 2, $ 3, etc..abc
el nuevo nombre del archivo terminará en .abc. No es necesario escapar del metacarácter de puntos aquí en la sección "reemplazar"/
fin de la expresión regularantes de
Después
Sugerencia:
rename
la opción 's -n es útil. Realiza una ejecución en seco y le muestra qué nombres cambiará, pero no realiza ningún cambio.fuente
--execdir
no pasó en primer lugar,./
por lo que\.\/
se puede omitir la parte de la expresión regular. Puede que sea porque estoy en OSX, no en ubuntuOtra forma portátil:
fuente
También vea la entrada sobre por qué no debe analizar
ls
.Editar: si tiene que usar basename, su sintaxis sería:
https://unix.stackexchange.com/questions/19654/changing-extension-to-multiple-files
fuente
Esto es lo que hice y funcionó bastante como quería. Usé el
mv
comando Tenía varios.3gp
archivos y quería cambiarles el nombre a todos.mp4
Aquí hay un breve resumen para ello:
Que simplemente escanea a través del directorio actual, recoge todos los archivos .3gp, luego cambia el nombre (usando el mv) a
ren-name_of_file.mp4
fuente
file.3gp
afile.3gp.mp4
, que podría no ser lo que la mayoría de la gente quiere..3gp
o.mp4
aquí fueron solo para fines ilustrativos.basename "$i" .mp4
para eliminar la extensión anterior en lugar de "ren- $ i.mp4".Encontré una manera fácil de lograr esto. Para cambiar las extensiones de muchos archivos de jpg a pdf, use:
fuente
Me gustaría usar el comando MMV del paquete del mismo nombre :
Los
;
partidos cero o más*/
y corresponde#1
en el reemplazo. El*
corresponde a#2
. La versión no recursiva seríafuente
Renombrar archivos y directorios con
find -execdir | rename
Si va a cambiar el nombre de los archivos y directorios no simplemente con un sufijo, entonces este es un buen patrón:
La
-execdir
opción impresionante hace uncd
en el directorio antes de ejecutar elrename
comando, a diferencia de-exec
.-depth
asegúrese de que el cambio de nombre ocurra primero en los niños y luego en los padres, para evitar posibles problemas con la falta de directorios principales.-execdir
es necesario porque el cambio de nombre no funciona bien con las rutas de entrada que no son de nombre base, por ejemplo, lo siguiente falla:El
PATH
pirateo es obligatorio porque-execdir
tiene un inconveniente muy molesto:find
es extremadamente obstinado y se niega a hacer nada-execdir
si tiene alguna ruta relativa en suPATH
variable de entorno, por ejemplo./node_modules/.bin
, no:Ver también: ¿Por qué usar la acción '-execdir' no es seguro para el directorio que está en la RUTA?
-execdir
es una extensión de búsqueda de GNU para POSIX .rename
está basado en Perl y proviene delrename
paquete. Probado en Ubuntu 18.10.Cambiar el nombre de la solución alternativa anticipada
Si sus rutas de entrada no provienen
find
, o si ha tenido suficiente de la molestia relativa de la ruta, podemos usar algunas anticipaciones de Perl para cambiar el nombre de los directorios de manera segura como en:No he encontrado un análogo conveniente para
-execdir
conxargs
: https://superuser.com/questions/893890/xargs-change-working-directory-to-file-path-before-executing/915686Se
sort -r
requiere para garantizar que los archivos vengan después de sus respectivos directorios, ya que las rutas más largas vienen después de las más cortas con el mismo prefijo.fuente