Cambiar por lotes un nome de ficheiro en Python engadindo unha cadea ou un número secuencial antes e despois do nome do ficheiro

Negocios

Cambia o nome de forma masiva mediante o módulo os e o módulo glob.

Use o módulo os e o módulo glob para cambiar e renomear os nomes dos ficheiros nun cartafol en masa engadindo cadeas ou números secuenciais antes e despois dos nomes dos ficheiros.

Exemplo de estrutura de ficheiros

Tome a seguinte estrutura de ficheiros como exemplo. Neste caso, suponse que só hai ficheiros (sen cartafoles) no cartafol.

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

Cousas a ter en conta

Dado que o proceso implica cambiar o nome do ficheiro, garda o ficheiro orixinal por separado para que se poida gardar en caso de falla.

Obter a lista de ficheiros co módulo glob

O módulo glob atopará todos os nomes de ruta que coincidan co patrón especificado segundo as regras empregadas polo shell de Unix.
glob — Unix style pathname pattern expansion — Python 3.10.0 Documentation

Por exemplo, a seguinte función pódese usar para obter unha lista de nomes de ficheiros e directorios no directorio actual.
glob.glob('./*')
O argumento pode ser un camiño absoluto ou un camiño relativo.

Neste exemplo, parecería o seguinte.

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, podes obter o seguinte, co camiño do argumento engadido.
./testdir/a.jpg

Tamén pode usar comodíns (*) para obter só extensións específicas, como se mostra a continuación.
glob.glob('./testdir/*.jpg')

Pódese utilizar a seguinte coincidencia de patróns.

  • *: Coincide con todo.
  • ?Coincide con calquera personaxe.
  • [abc]: Coincide cun único carácter de a, b ou c.
  • [!abc]: Coincide cun único carácter que non sexa a, b ou c

Cambiar o nome con os.rename()

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
Cambia o nome do ficheiro ou directorio src a dst.
os — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

Use a función rename() do módulo do sistema operativo, que o renomeará como o nome suxire.

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

Despois, a.jpg renomearase a a_000.jpg.

Xerando números secuenciais con cero con str.format()

Por exemplo, ao engadir números secuenciais a decenas de ficheiros, queremos usar “00” ou “11” en lugar de “0” ou “1”. Se queres encher os ceros deste xeito, utiliza o método str.format().

str.format(args,*wargs)
Realiza operacións de formato de cadea. A cadea que invoca este método pode conter caracteres normais ou campos de substitución separados por {}.Built-in Types — Python 3.10.0 Documentation

Sintaxe das cadeas de especificación de formato
A cadea de formato contén o “campo de substitución” entre corchetes {}.

A sintaxe do campo de substitución é a seguinte:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"

En termos máis sinxelos, o campo de substitución comeza por campo_name, o que fai que o valor do obxecto especificado sexa formateado e inserido na saída en lugar do campo de substitución. Despois do campo_name, o campo de conversión pode ir seguido dun signo de exclamación ‘! Despois do campo_name, o campo de conversión pode ir seguido dun signo de exclamación ‘! O formato_spec pódese escribir cun dous puntos ‘:’ ao final. Isto especifica o formato non predeterminado do valor que se vai substituír.
string — Common string operations — Python 3.10.0 Documentation

Se queres enchelo con 0 polo momento, fai o seguinte.

# 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

Exemplo de código para engadir unha cadea/número secuencial antes dun ficheiro

Primeiro, obtén o nome do ficheiro con os.path.basename(). Despois, engade unha cadea ou número secuencial diante do nome do ficheiro e concatenao co camiño orixinal con os.path.join().

O seguinte exemplo engade img_ á fronte de todos os nomes de ficheiros.

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)))

O resultado é o seguinte.

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

Se queres engadir números secuenciais, cambia a instrución for por algo así: enumerate() para obter os números contados en orde a partir de 0. Neste caso, o número énchese con tres díxitos.

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

Velaquí o resultado.

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

Se queres comezar con 1 en lugar de 0, establece o segundo argumento de enumerate en 1.

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

Vai así.

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

Exemplo de código para engadir unha cadea/número secuencial despois dun ficheiro

Use os.path.splitext() para dividir o ficheiro en extensión e ruta raíz, e despois engade cadeas ou números secuenciais ao camiño raíz. No seguinte exemplo, engádese _img despois de todos os nomes de ficheiros.

import os
import glob

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

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

O resultado é este.

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

Do mesmo xeito que se engade unha cadea/número secuencial antes dun ficheiro, cambie a instrución for ao engadir 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