Cambiar el nombre de cientos de archivos a la vez para una ordenación adecuada

23

Tengo un montón de archivos, toda la materia nombrado como 1.jpg, 2.jpg, 3.jpg, y así sucesivamente hasta que 1439.jpg, sin embargo, tengo un problema con uno de mis proyectos y alfabetizar. Por lo general, irá en el orden1.jpg , 10.jpg, 11.jpgy así sucesivamente.

Lo que necesito es alguna forma de nombrar los archivos para que estén en el formato como 00001.jpg hasta el final 01439.jpg.

¿Cómo podría hacer esto de manera rápida y eficiente?

Kaz Wolfe
fuente
Lo que está buscando es "clasificación natural", tal vez esto ayude: askubuntu.com/questions/41390/…
Fabian Blechschmidt
Respuesta que no es una respuesta directa? ls -v unix.stackexchange.com/questions/33909/…
WernerCD
+1 porque he intentado sin éxito hacer esto pyrenamer.
Parto
@FabianBlechschmidt, necesito esto en un programa que no sea para nautilus o similar. Es para un proyecto individual.
Kaz Wolfe
¿Creo que pensaste en implementar la clasificación natural? Pero entiendo, renombrar archivos es bastante fácil y si hace el trabajo, genial :)
Fabian Blechschmidt

Respuestas:

35

Ubuntu viene con un script llamado rename. Es solo un pequeño script de Perl que presenta una serie de potentes funciones de cambio de nombre masivo, pero la mejor (en este caso) es la capacidad de ejecutar Perl durante el reemplazo. El resultado es una solución verdaderamente compacta:

rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

Esto es similar a las printfrespuestas de otros estilos aquí, pero todo se maneja por nosotros. El código anterior es para un número de 5 dígitos (incluido un número variable de ceros a la izquierda).

Buscará y reemplazará la primera cadena de números que encuentre con una versión con relleno de cero y dejará el resto del nombre de archivo solo. Esto significa que no tiene que preocuparse demasiado por cargar cualquier extensión o prefijo.

Nota: esto no es completamente portátil. Muchas distribuciones usan rename.uldel util-linuxpaquete como su renamebinario predeterminado . Esta es una alternativa significativamente atrofiada (ver man rename.ul) que no entenderá lo anterior. Si desea esto en una plataforma que no utiliza el cambio de nombre de Perl, descubra cómo instalarlo primero.


Y aquí hay un arnés de prueba:

$ touch {1..19}.jpg

$ ls
10.jpg  12.jpg  14.jpg  16.jpg  18.jpg  1.jpg  3.jpg  5.jpg  7.jpg  9.jpg
11.jpg  13.jpg  15.jpg  17.jpg  19.jpg  2.jpg  4.jpg  6.jpg  8.jpg

$ rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

$ ls
00001.jpg  00005.jpg  00009.jpg  00013.jpg  00017.jpg
00002.jpg  00006.jpg  00010.jpg  00014.jpg  00018.jpg
00003.jpg  00007.jpg  00011.jpg  00015.jpg  00019.jpg
00004.jpg  00008.jpg  00012.jpg  00016.jpg

Y un ejemplo de prefijos (no estamos haciendo nada diferente):

$ touch track_{9..11}.mp3 && ls
track_10.mp3  track_11.mp3  track_9.mp3

$ rename 's/\d+/sprintf("%02d", $&)/e' *.mp3 && ls
track_09.mp3  track_10.mp3  track_11.mp3
Oli
fuente
Si yo fuera una persona Perl, esta sería la solución perfecta. Realmente aseado.
Pop
2
No utiliza ningún perl, solo una herramienta suministrada que ya está escrita en perl.
Rob
1
En este caso se hace afectar a un solo comando de Perl, pero no es exactamente levantar objetos pesados. sprintfen Perl se comporta de manera similar a sprintfen otros idiomas.
Oli
21
for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then  mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

Editar

Explicación:

  • if [[ $f =~ [0-9]+\. ]] se asegura de que solo se renombren los archivos cuyos nombres son números (seguidos de un punto).
  • printf "%.5d" NUMBER agrega los ceros a la izquierda
  • "${f%.*}" corta la extensión (.jpg) y deja solo el número
  • .jpgdespués de la segunda tecla de retroceso agrega la extensión de archivo nuevamente.

Tenga en cuenta que esto solo funcionará en los nombres de archivos que son números. Los ceros iniciales del margen izquierdo a archivos no numerados requerirían un formato diferente.

Si quieres experimentar, prueba este comando:

for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then echo mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

Editar 2

El comando se hizo más seguro al asegurarse de que solo se renombraran los nombres de archivo que son números. Tenga en cuenta que los archivos preexistentes nombrados como 00001.jpg se sobrescribirán.

sмurf
fuente
¡Este script de línea funciona 'fuera de la caja' en Ubuntu y otras distribuciones de Linux! 😃 No es necesario instalar ninguna herramienta adicional usando perl, python, etc.
HEXcube
6

Debajo de un script de Python.

El script agrega ceros a la izquierda hasta el número definido de dígitos. Si el nombre es más grande que eso, el archivo (nombre) está intacto.

La combinación de diferentes extensiones en una acción de cambio de nombre puede agregar algo de comodidad. Para agregar extensiones, simplemente agréguelas a la tupla, por ejemplo extensions = (".jpg", ".jpeg", ".tiff").

Copie el texto en un archivo vacío, guárdelo como rename.py, ingrese la ruta correcta al directorio de archivos ( sourcedir), el número de dígitos que desea que tengan los nuevos nombres ( number_ofdigits) y las extensiones de archivo para cambiar el nombre ( extensions)

Ejecútelo con el comando:

python3 /path/to/script/rename.py

La secuencia de comandos:

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; number_ofdigits = 5; extensions = (".jpg", ".jpeg")

files = os.listdir(sourcedir)
for item in files:
    if item.endswith(extensions):
        name = item.split("."); zeros = number_ofdigits-len(name[0])
        newname = str(zeros*"0")+name[0]+"."+name[1]
        shutil.move(sourcedir+"/"+item, sourcedir+"/"+newname)

editar:

Debajo de una versión ligeramente mejorada. Determina automáticamente el nombre más largo en el directorio y agrega ceros a la longitud del nombre más largo.

ejemplo:

1.jpg
12.jpg
123.jpg

se convierte en:

001.jpg
012.jpg
123.jpg

No es necesario establecer el número de dígitos.

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; extensions = (".jpg", ".jpeg")
files = [(f, f[f.rfind("."):], f[:f.rfind(".")]) for f in os.listdir(sourcedir)if f.endswith(extensions)]
maxlen = len(max([f[2] for f in files], key = len))

for item in files:
    zeros = maxlen-len(item[2])
    shutil.move(sourcedir+"/"+item[0], sourcedir+"/"+str(zeros*"0")+item[0])
Jacob Vlijm
fuente
2

Hay una utilidad de cambio de nombre implementada en Perl que hace esto muy fácil:

rename 's/\d+/sprintf("%05d",$&)/e' *.jpg

El primer argumento es una expresión de Perl que se evalúa para cada nombre de archivo.

Mats Kindahl
fuente
0

Hay una GUI que hará esto llamada pyRenamer que se puede encontrar en los repositorios. Instale, inicie, seleccione su directorio y simplemente configure el 'Patrón de nombre de archivo renombrado' en '{num5}' en la pestaña 'Patrones' y haga clic en el botón 'Cambiar nombre'. También puede obtener una vista previa de lo que sucederá antes de cambiar el nombre.

usuario287888
fuente
Si bien su respuesta sí funciona, tenga en cuenta que esta es una shell-scriptingsección, lo que significa que estoy buscando una respuesta de línea de comandos. Además, ¿puede proporcionar más detalles sobre el programa? Por ejemplo, ¿qué formato de patrón es {num5}?
Kaz Wolfe
-4
for file in `(find * -maxdepth 1 -type f -name "*.jpg")`     
do    
  mv $file "000"$file    
done

Esto es crudo, ya que no cambia el nombre de forma inteligente, tendrá que pensar en un truco para eso. Pero debería ayudarte a ordenar las cosas.

Actualización: Bueno, tienes una respuesta más completa.

Swarnendu Biswas
fuente
2
cambia el nombre de 1439.jpg como 0001439.jpg.
Avinash Raj
Sí, lo sé, solo rellenamos ceros adicionales que aún deberían funcionar con el tipo.
Swarnendu Biswas