Jak zmienić nazwę pliku za pomocą Pythona

Odpowiedzi:

578

Użyj os.rename:

import os

os.rename('a.txt', 'b.kml')
TY
źródło
52
Należy zauważyć, że jeśli plików nie ma w katalogu roboczym, potrzebna będzie pełna ścieżka.
EndermanAPM
nie bardzo, na Ubuntu 3.7, działa dla mnie przy użyciu ścieżek względnych
toing_toing
2
@toing_toing oczywiście działa, on prawdopodobnie oznacza po prostu, że powinieneś być świadomy bieżącego katalogu i albo podać ścieżkę względną do niego, albo po prostu użyć ścieżki bezwzględnej (jak C:/folder/file.txtw Windows lub /home/file.txtLinux / MacOS).
Alex P.
Warto zauważyć, że spowoduje to dyskretne nadpisanie plików w systemach uniksopodobnych, ale zakończy się niepowodzeniem OSErrorw systemach Windows. os.path.existsnależy użyć do sprawdzenia, czy cel istnieje przed zmianą nazwy. Powoduje to powstanie błędu „Czas sprawdzenia do czasu użycia”, ale jest mało prawdopodobne, aby powodował problemy. (Nie znam łatwego sposobu na obejście tego - patrz tutaj .
AnnanFay,
2
Jeśli użytkownik naprawdę chce zastąpić plik w dowolnym systemie operacyjnym, należy użyćos.replace
LucG
72

Plik może znajdować się w katalogu, w takim przypadku określ ścieżkę:

import os
old_file = os.path.join("directory", "a.txt")
new_file = os.path.join("directory", "b.kml")
os.rename(old_file, new_file)
Abdul Razak
źródło
48
import shutil

shutil.move('a.txt', 'b.kml')

Działa to w celu zmiany nazwy lub przeniesienia pliku.

Andy Balaam
źródło
31
shutil.movenie jest dobrą opcją, ponieważ nie jest operacją atomową. Jeśli plik jest otwarty, na przykład shutil.moveutworzy plik new_name, ale nie usunie go, old_namepozostawiając dwa pliki. os.renamez drugiej strony nic nie zrobi, co jest lepszą opcją . Dzięki shutil.move, nawet jeśli złapiesz błąd, nadal będziesz musiał się martwić o sprawdzenie i usunięcie nieuczciwego pliku. Po prostu nie warto, kiedy istnieje lepsze narzędzie:os.rename .
mvbentes,
34

Od wersji Python 3.4 można to rozwiązać za pomocą modułu pathlib .

Jeśli akurat używasz starszej wersji, możesz skorzystać z wersji z backportowaną wersją, którą znajdziesz tutaj

Załóżmy, że nie znajdujesz się w ścieżce katalogu głównego (aby dodać trochę trudności), której nazwę chcesz zmienić, i musisz podać pełną ścieżkę, możemy na to spojrzeć:

some_path = 'a/b/c/the_file.extension'

Możesz więc obrać ścieżkę i utworzyć Pathz niej obiekt:

from pathlib import Path
p = Path(some_path)

Aby dostarczyć trochę informacji o tym obiekcie, który mamy teraz, możemy z niego wyciągnąć różne rzeczy. Na przykład, jeśli z jakiegokolwiek powodu chcemy zmienić nazwę pliku, zmieniając nazwę pliku z the_filena the_file_1, możemy uzyskać część nazwy pliku:

name_without_extension = p.stem

I nadal trzymaj przedłużenie w ręku:

ext = p.suffix

Możemy wykonać naszą modyfikację za pomocą prostej manipulacji ciągiem:

Python 3.6 i nowsze wersje używają f-stringów!

new_file_name = f"{name_without_extension}_1"

Inaczej:

new_file_name = "{}_{}".format(name_without_extension, 1)

A teraz możemy wykonać naszą zmianę nazwy, wywołując renamemetodę na utworzonym obiekcie ścieżki i dołączając ją, extaby ukończyć odpowiednią strukturę zmiany nazwy:

p.rename(Path(p.parent, new_file_name + ext))

Krótko mówiąc, aby pokazać jego prostotę:

Python 3.6+:

from pathlib import Path
p = Path(some_path)
p.rename(Path(p.parent, f"{p.stem}_1_{p.suffix}"))

Wersje mniejsze niż Python 3.6 używają zamiast tego metody formatu ciągu:

from pathlib import Path
p = Path(some_path)
p.rename(Path(p.parent, "{}_{}_{}".format(p.stem, 1, p.suffix))
idjaw
źródło
3
Dlaczego miałbyś to zrobić zamiast przyjętej odpowiedzi? Wydaje się o wiele bardziej skomplikowane
rbennell,
19
Cóż @rbennell, większość tej odpowiedzi jest wyjaśnieniem. Odpowiedź to tak naprawdę tylko trzy linie na końcu. Co więcej, przyjęta odpowiedź została udzielona wyraźnie dla samej zmiany nazwy. Ta odpowiedź stanowi sposób pokazania, w jaki sposób można manipulować nazwą pliku, aby zachować wybrane części na ścieżce lub nazwie pliku. Co więcej, pathlibbiblioteka została wprowadzona w Pythonie 3.4, więc dzielenie się odpowiedzią tutaj zapewnia również ekspozycję solidnego modułu, aby pokazać jego wszechstronność i wykorzystanie dla bardziej skomplikowanych wymagań.
idjaw
4
Dziękuję @idjaw, twój komentarz jest dobrą odpowiedzią na podstawowe pytanie nas początkujących, prosty Dlaczego to zrobiłeś? . Co więcej, odświeżające jest nieprzyjazne podejście do Internetu do tego, co często uważa się za ignorancję.
Igor V.
3
@SasukeUchiha - {}służą do formatowania ciągów, o których można przeczytać tutaj . Ostatecznie dzieje się tak, że {}get jest zastępowany zmiennymi przekazywanymi do formatmetody. Tak więc pierwszy {}będzie zawierał to, co jest w środku name_without_extension, a drugi zawiera drugi argument, który jest po prostu 1.
idjaw
3
Korzystanie z f-stringów jeszcze bardziej upraszcza. z importu pathlib Ścieżka p = ścieżka (some_path) wersja = 1 p. nazwa (ścieżka (p.parent, f "{p.stem} _ {wersja}" + p.suffix))
Liquidgenius
8

Zastosowanie os.rename. Ale musisz przekazać pełną ścieżkę obu plików do funkcji. Jeśli mam plik a.txtna pulpicie, zrobię to i muszę też podać pełny plik o zmienionej nazwie.

 os.rename('C:\\Users\\Desktop\\a.txt', 'C:\\Users\\Desktop\\b.kml')
Samotny wilk
źródło
1
„Muszę” nie jest prawdą. Zawsze możesz zastąpić względną nazwę pliku bezwzględną nazwą pliku i odwrotnie. Początkowo gryzie początkujących, ponieważ nie rozumieją, jak względne nazwy plików odnoszą się do bieżącego katalogu roboczego.
tripleee
3
import os

# Set the path
path = 'a\\b\\c'  
# save current working directory
saved_cwd = os.getcwd()
# change your cwd to the directory which contains files
os.chdir(path)
os.rename('a.txt', 'b.klm')
# moving back to the directory you were in 
os.chdir(saved_cwd)
Tilak M. Divakar
źródło
1
Uważaj na robienie tego w ten sposób. Nie zawsze możesz chdir()przejść do katalogu, np. Co dzieje się w systemie Windows, gdy jest to UNC? I robienie chdir()ma skutki uboczne. Wolę po prostu określić niezbędne ścieżki do os.rename()bezpośredniego, bez chdir()ing.
JonBrave,
0

Możesz użyć os.system, aby wywołać terminal w celu wykonania zadania:

os.system('mv oldfile newfile')

źródło
tak, będzie to działać tylko na komputerze z systemem uniksowym, podobnie jak mvwbudowany program wiersza polecenia unix do przenoszenia / zmiany nazwy pliku.
Michaił Geyer,
8
Dlaczego miałbyś wywoływać terminal i zdefiniować komendę UNIX, skoro możesz to zrobić z Pythona na wiele platform?
EndermanAPM
0
import os
import re
from pathlib import Path

for f in os.listdir(training_data_dir2):
  for file in os.listdir( training_data_dir2 + '/' + f):
    oldfile= Path(training_data_dir2 + '/' + f + '/' + file)
    newfile = Path(training_data_dir2 + '/' + f + '/' + file[49:])
    p=oldfile
    p.rename(newfile)
issam
źródło
1
Twarde kodowanie do przodu jako separator ścieżek i mieszanie starego stylu os.pathz nowoczesnością pathlibjest dość niepewne. pathlibZamiast tego idź na całość .
tripleee
0
import shutil
import os

files = os.listdir("./pics/") 

for key in range(0, len(files)):
   print files[key]
   shutil.move("./pics/" + files[key],"./pics/img" + str(key) + ".jpeg")

To powinno to zrobić. python 3+

Naveen
źródło
... lub użyj wyliczenia dla nieco bardziej czytelnej wersji: dla klucza, fname w wyliczeniu (pliki):…
Nicolas D