Wsadowa zmiana nazwy pliku w Pythonie poprzez dodanie ciągu znaków lub liczby porządkowej przed i po nazwie pliku

Biznes

Zmieniaj nazwy masowo za pomocą modułu os i modułu glob.

Użyj modułu os i modułu glob do masowej zmiany i zmiany nazw plików w folderze poprzez dodanie ciągów znaków lub numerów sekwencyjnych przed i po nazwach plików.

Przykładowa struktura pliku

Weźmy jako przykład następującą strukturę plików. W tym przypadku zakłada się, że w folderze znajdują się tylko pliki (bez folderów).

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

Rzeczy, o których należy pamiętać

Ponieważ proces obejmuje zmianę nazwy pliku, zapisz oryginalny plik oddzielnie, aby można go było zapisać w przypadku niepowodzenia.

Pobierz listę plików za pomocą modułu glob

Moduł glob znajdzie wszystkie nazwy ścieżek pasujące do podanego wzorca, zgodnie z regułami używanymi przez powłokę uniksową.
glob — Unix style pathname pattern expansion — Python 3.10.0 Documentation

Na przykład, poniższa funkcja może być użyta do uzyskania listy nazw plików i katalogów w bieżącym katalogu.
glob.glob('./*')
Argumentem może być ścieżka bezwzględna lub względna.

W tym przykładzie wyglądałoby to następująco.

import glob

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

Zamiast a.jpg, możesz otrzymać następujący plik, z dodaną ścieżką argumentu.
./testdir/a.jpg

Możesz również użyć symboli wieloznacznych (*), aby uzyskać tylko określone rozszerzenia, jak pokazano poniżej.
glob.glob('./testdir/*.jpg')

Można zastosować następujące dopasowanie wzorca.

  • *: Pasuje do wszystkiego.
  • ?Dopasowuje dowolny pojedynczy znak.
  • [abc]: Dopasowuje pojedynczy znak z a, b, lub c.
  • [!abc]: Dopasowuje pojedynczy znak inny niż a, b, lub c

Zmień nazwę za pomocą os.rename()

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
Zmienia nazwę pliku lub katalogu src na dst.
os — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

Użyj funkcji rename() z modułu os, która zmieni nazwę na taką, jaką sugeruje nazwa.

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

Następnie nazwa pliku a.jpg zostanie zmieniona na a_000.jpg.

Generowanie liczb sekwencyjnych z wypełnieniem zerowym za pomocą str.format()

Na przykład, gdy dodajemy kolejne numery do kilkudziesięciu plików, chcemy użyć „00” lub „11” zamiast „0” lub „1”. Jeśli chcesz wypełnić zera w ten sposób, użyj metody str.format().

str.format(args,*kwargs)
Wykonuje operacje formatowania łańcuchów. Łańcuch, który wywołuje tę metodę może zawierać zwykłe znaki lub pola zastępcze oddzielone {}.Built-in Types — Python 3.10.0 Documentation

Składnia łańcuchów specyfikacji formatu
Łańcuch formatujący zawiera „pole zastępcze” ujęte w nawiasy klamrowe {}.

Składnia pola wymiany jest następująca:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"

Mówiąc prościej, pole zastępcze zaczyna się od field_name, co powoduje, że wartość określonego obiektu zostanie sformatowana i wstawiona do wyjścia zamiast pola zastępczego. Po polu_nazwy, po polu konwersji może następować wykrzyknik '! Po polu_nazwy, po polu konwersji może następować wykrzyknik '! Format_spec może być zapisany z dwukropkiem ':' na końcu. Określa to nie-domyślny format wartości, która ma zostać zastąpiona.
string — Common string operations — Python 3.10.0 Documentation

Jeśli chcesz na razie wypełnić go cyfrą 0, wykonaj następujące czynności.

# 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

Przykład kodu dodającego numer kolejny łańcucha przed plikiem

Najpierw, pobierz nazwę pliku za pomocą os.path.basename(). Następnie dodaj ciąg znaków lub liczbę porządkową przed nazwą pliku i połącz ją z oryginalną ścieżką za pomocą os.path.join().

Poniższy przykład dodaje img_ na początku wszystkich nazw plików.

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

Wynik jest następujący.

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

Jeśli chcesz dodać kolejne liczby, zmień instrukcję for na coś takiego: enumerate() aby otrzymać liczby liczone w kolejności od 0. W tym przypadku liczba jest wypełniona trzema cyframi.

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

Oto wynik.

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

Jeśli chcesz zacząć od 1 zamiast 0, ustaw drugi argument enumerate na 1.

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

To idzie tak.

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

Przykład kodu dodającego kolejny ciąg znaków po pliku

Użyj os.path.splitext() aby podzielić plik na rozszerzenie i ścieżkę główną, a następnie dodaj łańcuchy lub liczby sekwencyjne do ścieżki głównej. W poniższym przykładzie, _img jest dodawane po wszystkich nazwach plików.

import os
import glob

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

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

Rezultat jest taki.

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

Podobnie jak w przypadku dodawania numeru kolejnego łańcucha przed plikiem, zmień instrukcję for podczas dodawania numeru kolejnego.

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