2012-01-13 18 views
458

Zajrzałem do interfejsu Pythona os, ale nie udało mi się znaleźć metody przeniesienia pliku. Jak zrobiłbym odpowiednik $ mv ... w Pythonie?Jak przenieść plik w Pythonie

>>> source_files = '/PATH/TO/FOLDER/*' 
>>> destination_folder = 'PATH/TO/FOLDER' 
>>> # equivalent of $ mv source_files destination_folder 
+0

dla tych, którzy znają polecenie [gnu-coreutils] 'mv' (https://www.gnu.org/software/coreutils/manual/html_node/mv-invocation.html), python's' shutil.move 'ma jeden przypadek krawędzi, w którym funkcja' shutil.move' różni się. [Przejdź tutaj w celu pełnego napisania] (https://stackoverflow.com/questions/31813504). ** W skrócie, 'shutil Pythona.move' podniesie wyjątek (ale gnu-coreutils 'mv' nie będzie) ** kiedy twój cel jest katalogiem, a katalog ma już plik o tej samej nazwie co źródło (ponownie po więcej informacji zobacz link podany w poprzednie zdanie). –

Odpowiedz

664

os.rename() lub shutil.move()

Oba wykorzystują tę samą składnię:

os.rename("path/to/current/file.foo", "path/to/new/desination/for/file.foo") 
shutil.move("path/to/current/file.foo", "path/to/new/destination/for/file.foo") 

zauważyć, że w obu przypadkach katalog, w którym tworzony jest nowy plik musi już istnieć (ale na Windows, plik o tej nazwie nie może być lub zostanie zgłoszony wyjątek). Należy również uwzględnić nazwę pliku (file.foo) zarówno w argumencie źródłowym, jak i docelowym. Jeśli zostanie zmieniony, plik zostanie zmieniony i przeniesiony.

Jak zauważono w komentarzach do innych odpowiedzi, w większości przypadków shutil.move po prostu wywołuje os.rename. Jeśli jednak miejsce docelowe znajduje się na innym dysku niż źródło, zamiast tego skopiuje, a następnie usunie plik źródłowy.

+4

Czy jestem jedynym, który myśli, że os.rename nie działa dla katalogów? Cytuję: "Jeśli dst jest katalogiem, OSError zostanie podniesiony." – Fabian

+12

'shutil.move' działa dla katalogów. Możesz użyć ścieżki względnej 'shutil.move (f.name," tmp/")' lub pełnej ścieżki 'shutil.move (f.name,"/Users/hello/tmp/")', ** nie używaj * * ** '~' ** w ścieżce, sprawdzone w python2.7.9, Mac OS X. – whyisyoung

+2

'' 'jest konstrukcją powłoki i nie ma nic wspólnego ze ścieżkami plików per se, poza konwencją nieumiejętną. Jeśli naprawdę chcesz włączyć katalog domowy, użyj 'os.getenv ('HOME')', łącząc je z częściami żądanej ścieżki, jeśli to konieczne. – amn

30

W przypadku pliku os.rename lub shutil.move należy zaimportować moduł. Znak * nie jest wymagany, aby przenieść wszystkie pliki.

Mamy folder w/opt/awesome nazwie źródła z jednym plikiem o nazwie awesome.txt.

in /opt/awesome 
○ → ls 
source 
○ → ls source 
awesome.txt 

python 
>>> source = '/opt/awesome/source' 
>>> destination = '/opt/awesome/destination' 
>>> import os 
>>> os.rename(source, destination) 
>>> os.listdir('/opt/awesome') 
['destination'] 

Użyliśmy os.listdir aby zobaczyć, że nazwa folderu w rzeczywistości zmieniło. Oto zamknięcie przesuwające cel z powrotem do źródła.

>>> import shutil 
>>> shutil.move(destination, source) 
>>> os.listdir('/opt/awesome/source') 
['awesome.txt'] 

Tym razem sprawdziłem w folderze źródłowym, aby upewnić się, że utworzony plik awesome.txt istnieje. Jest tam :)

Teraz przenieśliśmy folder i jego pliki ze źródła do miejsca docelowego iz powrotem.

+4

http://docs.python.org/2/library/shutil.html Ta dokumentacja pokazuje, że masz zmienione parametry dla metody shutil.move. – mac10688

+1

Użyłem miejsca docelowego i źródła odwróconego, aby zobaczyć, że pliki zostały przeniesione ze źródła, a następnie z powrotem do niego .... Widziałem, jak to jest niejasne. – jmontross

180

Chociaż os.rename() i shutil.move() zmienią nazwy plików, polecenie najbliższe komendzie Unix mv to shutil.move(). Różnica polega na tym, że os.rename() nie działa, jeśli źródło i miejsce docelowe znajdują się na różnych dyskach, podczas gdy shutil.move() nie obchodzi, na którym dysku znajdują się pliki.

+52

'shutil.move()' używa 'os.rename()' jeśli miejsce docelowe znajduje się w bieżącym systemie plików. W przeciwnym razie 'shutil.move()' kopiuje źródło do miejsca docelowego za pomocą 'shutil.copy2()', a następnie usuwa źródło. –

+7

Uważaj, aby zdać sobie sprawę, że ['shutil.copy2()' nie może skopiować wszystkich metadanych pliku] (https://docs.python.org/2/library/shutil.html), więc jeśli tak się stanie, to jest tak jak robienie ' cp -p', a następnie 'rm', rozumiem. – 2rs2ts

+9

Należy pamiętać: plik shutil.move w Pythonie 2.7.3 kończy się niepowodzeniem, jeśli cel już istnieje. Jeśli to możliwe, złap błąd lub ręcznie usuń plik/katalog, a następnie wykonaj ruch. – Dana

8

Przyjęta odpowiedź nie jest właściwa, ponieważ pytanie nie dotyczy zmiany nazwy pliku w pliku, ale przeniesienia wielu plików do katalogu. shutil.move wykona pracę, ale w tym celu os.rename jest bezużyteczny (jak podano w komentarzach), ponieważ miejsce docelowe musi mieć jawną nazwę pliku.

5

To właśnie używam w tej chwili:

import os, shutil 
path = "/volume1/Users/Transfer/" 
moveto = "/volume1/Users/Drive_Transfer/" 
files = os.listdir(path) 
files.sort() 
for f in files: 
    src = path+f 
    dst = moveto+f 
    shutil.move(src,dst) 

teraz w pełni funkcjonalne. Mam nadzieję, że to ci pomoże.

Powiązane problemy