Lote alterar um nome de ficheiro em Python adicionando uma string ou número sequencial antes e depois do nome do ficheiro

O negócio

Renomear a granel utilizando o módulo os e o módulo glob.

Utilizar o módulo os e o módulo glob para alterar e renomear os nomes dos ficheiros numa pasta em massa, adicionando cadeias de caracteres ou números sequenciais antes e depois dos nomes dos ficheiros.

Exemplo de estrutura de ficheiro

Tomar como exemplo a seguinte estrutura de ficheiro. Neste caso, supõe-se que existem apenas ficheiros (sem pastas) na pasta.

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

Coisas a ter em mente

Uma vez que o processo envolve renomear o ficheiro, guardar o ficheiro original separadamente para que possa ser guardado em caso de falha.

Obter a lista de ficheiros com o módulo glob

O módulo glob encontrará todos os padrões que correspondem ao padrão especificado de acordo com as regras utilizadas pela concha Unix.
glob — Unix style pathname pattern expansion — Python 3.10.0 Documentation

Por exemplo, a seguinte função pode ser usada para obter uma lista de nomes de ficheiros e directórios no directório actual.
glob.glob('./*')
O argumento pode ser um caminho absoluto ou um caminho relativo.

Neste exemplo, pareceria o seguinte.

import glob

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

Em vez de a.jpg, pode obter o seguinte, com o caminho de argumento adicionado.
./testdir/a.jpg

Também pode usar wildcards (*) para obter apenas extensões específicas, como se mostra abaixo.
glob.glob('./testdir/*.jpg')

Pode ser utilizada a seguinte correspondência de padrões.

  • *: Corresponde a tudo.
  • ?Corresponde a qualquer carácter individual.
  • [abc]: Combina um único carácter de a, b, ou c.
  • [!abc]: Corresponde a um único carácter que não seja a, b, ou c

Renomear com os.renome()

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
Renomear o ficheiro ou directório src para dst.
os — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

Utilizar a função renome() do módulo de os, que lhe dará o nome que o nome sugere.

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

Então, a.jpg será renomeado para a_000.jpg.

Geração de números sequenciais de preenchimento zero com formato str.format()

Por exemplo, ao adicionar números sequenciais a dezenas de ficheiros, queremos usar “00” ou “11” em vez de “0” ou “1”. Se quiser preencher os zeros desta forma, utilize o método str.format().

str.format(args,*kwargs)
Realiza operações de formatação de cordas. A string que invoca este método pode conter caracteres normais ou campos de substituição separados por {}.Built-in Types — Python 3.10.0 Documentation

Sintaxe das cordas de especificação de formato
A cadeia de formatação contém o “campo de substituição” delimitado entre parênteses rectos {}.

A sintaxe do campo de substituição é a seguinte:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"

Em termos mais simples, o campo de substituição começa com field_name, o que faz com que o valor do objecto especificado seja formatado e inserido na saída em vez do campo de substituição. Após o nome_do_campo, o campo de conversão pode ser seguido por um ponto de exclamação '! Após o nome_do_campo, o campo de conversão pode ser seguido por um ponto de exclamação '! O formato_espec pode ser escrito com dois pontos ':' no final. Isto especifica o formato não predefinido do valor a ser substituído.
string — Common string operations — Python 3.10.0 Documentation

Se quiser preenchê-lo com 0 por agora, faça 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 adicionar uma string\ número sequencial antes de um ficheiro

Primeiro, obter o nome do ficheiro com os.path.basename(). Depois, adicionar uma string ou número sequencial em frente do nome do ficheiro, e concatená-lo com o caminho original com os.path.join().

O exemplo seguinte acrescenta img_ à frente 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 quiser adicionar números sequenciais, altere o for para algo como isto: enumere() para que os números sejam contados por ordem a partir de 0. Neste caso, o número é preenchido com três dígitos.

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

Aqui está o resultado.

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

Se quiser começar com 1 em vez de 0, defina o segundo argumento de enumerar para 1.

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

É assim.

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

Exemplo de código para adicionar um número sequencial após um ficheiro

Utilizar os.path.splitext() para dividir o ficheiro em extensão e caminho de raiz, e depois adicionar cordas ou números sequenciais ao caminho de raiz. No exemplo seguinte, _img é adicionado depois de todos os nomes de ficheiro.

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

Tal como com a adição de um número sequencial de cadeia de caracteres antes de um ficheiro, altere o for ao adicionar um número sequencial.

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