Cambie por lotes el nombre de un archivo en Python añadiendo una cadena o un número secuencial antes y después del nombre del archivo

Negocio

Renombrar en bloque utilizando el módulo os y el módulo glob.

Utilice el módulo os y el módulo glob para cambiar y renombrar los nombres de los archivos de una carpeta de forma masiva añadiendo cadenas o números secuenciales antes y después de los nombres de los archivos.

Ejemplo de estructura de archivos

Tome como ejemplo la siguiente estructura de archivos. En este caso, se supone que sólo hay archivos (no carpetas) en la carpeta.

.
└── testdir
    ├── a.jpg
    ├── b.jpg
    ├── c.jpg
    ├── d.jpg
    └── e.jpg

Cosas a tener en cuenta

Dado que el proceso implica cambiar el nombre del archivo, guarde el archivo original por separado para poder guardarlo en caso de fallo.

Obtener la lista de archivos con el módulo glob

El módulo glob encontrará todos los nombres de ruta que coincidan con el patrón especificado según las reglas utilizadas por el shell de Unix.
glob — Unix style pathname pattern expansion — Python 3.10.0 Documentation

Por ejemplo, la siguiente función puede utilizarse para obtener una lista de nombres de archivos y directorios en el directorio actual.
glob.glob('./*')
El argumento puede ser una ruta absoluta o una ruta relativa.

En este ejemplo, tendría el siguiente aspecto.

import glob

print(glob.glob('./testdir/*'))
# => ['./testdir/a.jpg', './testdir/b.jpg', './testdir/c.jpg', './testdir/d.jpg', './testdir/e.jpg']

En lugar de a.jpg, puede obtener lo siguiente, añadiendo la ruta del argumento.
./testdir/a.jpg

También puede utilizar comodines (*) para obtener sólo extensiones específicas, como se muestra a continuación.
glob.glob('./testdir/*.jpg')

Se puede utilizar la siguiente concordancia de patrones.

  • *: Coincide con todo.
  • ?Coincide con cualquier carácter individual.
  • [abc]: Coincide con un solo carácter de a, b o c.
  • [!abc]: Coincide con un solo carácter que no sea a, b o c

Renombrar con os.rename()

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
Renombra el archivo o directorio src a dst.
os — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

Utilice la función rename() del módulo os, que lo renombrará como su nombre indica.

import os
os.rename('./testdir/a.jpg', './testdir/a_000.jpg')

Entonces, a.jpg será renombrado a a_000.jpg.

Generación de números secuenciales rellenos de cero con str.format()

Por ejemplo, al añadir números secuenciales a docenas de archivos, queremos utilizar «00» u «11» en lugar de «0» o «1». Si quieres rellenar los ceros de esta manera, utiliza el método str.format().

str.format(args,*kwargs)
Realiza operaciones de formateo de cadenas. La cadena que invoca este método puede contener caracteres normales o campos de sustitución separados por {}.Built-in Types — Python 3.10.0 Documentation

Sintaxis de las cadenas de especificación del formato
La cadena de formato contiene el «campo de sustitución» encerrado entre llaves {}.

La sintaxis del campo de sustitución es la siguiente:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"

En términos más sencillos, el campo de sustitución comienza con nombre_de_campo, lo que hace que se formatee el valor del objeto especificado y se inserte en la salida en lugar del campo de sustitución. Después de field_name, el campo de conversión puede ir seguido de un signo de exclamación '! Después de field_name, el campo de conversión puede ir seguido de un signo de exclamación '! El format_spec puede escribirse con dos puntos ':' al final. Esto especifica el formato no predeterminado del valor que se va a sustituir.
string — Common string operations — Python 3.10.0 Documentation

Si quieres llenarlo con 0 por ahora, haz lo siguiente.

# 3を2桁でゼロ埋め
print('{0:02d}'.format(3))
# => 03

# Fill in the zeros with three and four digits for 4 and 6, respectively.
print('{0:03d}, {1:04d}'.format(4, 6))
# => 004, 0006

Ejemplo de código para añadir un número secuencial antes de un archivo

Primero, obtenga el nombre del archivo con os.path.basename(). A continuación, añada una cadena o un número secuencial delante del nombre del archivo, y concaténelo con la ruta original con os.path.join().

El siguiente ejemplo añade img_ al frente de todos los nombres de archivo.

import os
import glob

path = "./testdir"
files = glob.glob(path + '/*')

for f in files:
    os.rename(f, os.path.join(path, 'img_' + os.path.basename(f)))

El resultado es el siguiente.

.
└── testdir
    ├── img_a.jpg
    ├── img_b.jpg
    ├── img_c.jpg
    ├── img_d.jpg
    └── img_e.jpg

Si quiere añadir números secuenciales, cambie la sentencia for por algo como esto: enumerate() para obtener los números contados en orden desde 0. En este caso, el número se rellena con tres dígitos.

for i, f in enumerate(files):
    os.rename(f, os.path.join(path, '{0:03d}'.format(i) +
                              '_' + os.path.basename(f)))

Este es el resultado.

.
└── testdir
    ├── 000_a.jpg
    ├── 001_b.jpg
    ├── 002_c.jpg
    ├── 003_d.jpg
    └── 004_e.jpg

Si desea comenzar con 1 en lugar de 0, establezca el segundo argumento de enumerar en 1.

for i, f in enumerate(files, 1):
    os.rename(f, os.path.join(path, '{0:03d}'.format(i) +
                              '_' + os.path.basename(f)))

Es así.

.
└── testdir
    ├── 001_a.jpg
    ├── 002_b.jpg
    ├── 003_c.jpg
    ├── 004_d.jpg
    └── 005_e.jpg

Ejemplo de código para añadir un número secuencial después de un archivo

Utilice os.path.splitext() para dividir el archivo en la extensión y la ruta raíz, y luego añada cadenas o números secuenciales a la ruta raíz. En el siguiente ejemplo, se añade _img después de todos los nombres de archivo.

import os
import glob

files = glob.glob('./testdir/*')

for f in files:
    ftitle, fext = os.path.splitext(f)
    os.rename(f, ftitle + '_img' + fext)

El resultado es este.

.
└── testdir
    ├── a_img.jpg
    ├── b_img.jpg
    ├── c_img.jpg
    ├── d_img.jpg
    └── e_img.jpg

Al igual que con la adición de un número secuencial de cadena antes de un archivo, cambiar la sentencia for cuando se añade un número secuencial.

for i, f in enumerate(files):
    ftitle, fext = os.path.splitext(f)
    os.rename(f, ftitle + '_' + '{0:03d}'.format(i) + fext)
.
└── testdir
    ├── a_000.jpg
    ├── b_001.jpg
    ├── c_002.jpg
    ├── d_003.jpg
    └── e_004.jpg
Copied title and URL