Zajrzałem do os
interfejsu Pythona , ale nie byłem w stanie znaleźć metody przeniesienia pliku. Jak mam zrobić odpowiednik $ mv ...
w Pythonie?
>>> source_files = '/PATH/TO/FOLDER/*'
>>> destination_folder = 'PATH/TO/FOLDER'
>>> # equivalent of $ mv source_files destination_folder
python
file
file-handling
David542
źródło
źródło
mv
polecenia , Pythonshutil.move
ma jeden przypadek krawędzi, gdzieshutil.move
różni funkcyjnych. Idź tutaj, aby napisać cały tekst . W skrócie, Pythonshutil.move
zgłosi wyjątek (ale gnu-coreutilsmv
tego nie zrobi), gdy miejscem docelowym jest katalog, a katalog ma już plik o tej samej nazwie co źródło (ponownie, aby uzyskać więcej informacji, zobacz link podany w poprzednim zdaniu ).os.system("mv file1 file2")
?Odpowiedzi:
os.rename()
,shutil.move()
lubos.replace()
Wszystkie stosują tę samą składnię:
Pamiętaj, że musisz podać nazwę pliku (
file.foo
) zarówno w argumentach źródłowym, jak i docelowym. Jeśli zostanie zmieniony, nazwa pliku zostanie zmieniona, a także przeniesiona.Zauważ również, że w pierwszych dwóch przypadkach katalog, w którym tworzony jest nowy plik, musi już istnieć. W systemie Windows plik o tej nazwie nie może istnieć lub zostanie zgłoszony wyjątek, ale
os.replace()
po cichu zastąpi plik nawet w takim przypadku.Jak zauważono w komentarzach do innych odpowiedzi, w większości przypadków
shutil.move
po prostu dzwonios.rename
. Jeśli jednak miejsce docelowe znajduje się na innym dysku niż źródło, skopiuje, a następnie usunie plik źródłowy.źródło
shutil.move
działa dla katalogów. Możesz użyć ścieżki względnejshutil.move(f.name, "tmp/")
lub pełnejshutil.move(f.name, "/Users/hello/tmp/")
, nie używaj jej~
na ścieżce, zaznaczone w python2.7.9, Mac OS X.~
jest konstrukcją powłoki i nie ma nic wspólnego ze ścieżkami plików jako takimi, jak złą konwencją. Jeśli naprawdę chcesz zaangażować swój katalog domowy, użyjos.getenv('HOME')
zamiast tego, łącząc go z częściami pożądanej ścieżki, jeśli to konieczne.os.path.expanduser()
aby poprawnie rozwinąć „~
” zgodnie z regułami specyficznymi dla systemu operacyjnego. Znacznie fajniejsze, ponieważ%HOME%
nie zawsze jest ustawione w systemie Windows.os.rename
nie obsługuje plików na różnych urządzeniach. Użyj,shutil.move
jeśli nie masz pewności, czy plik źródłowy i docelowy znajdują się na tym samym urządzeniu.Mimo
os.rename()
ishutil.move()
oba będą zmieniać nazwy plików, najbliższe jest polecenie Univ mvshutil.move()
. Różnica polega na tym,os.rename()
że nie działa, jeśli źródło i miejsce docelowe znajdują się na różnych dyskach, ashutil.move()
nie obchodzi, na jakim dysku znajdują się pliki.źródło
shutil.move()
używa,os.rename()
jeśli miejsce docelowe znajduje się w bieżącym systemie plików. W przeciwnym razieshutil.move()
kopiuje źródło do miejsca docelowego za pomocą,shutil.copy2()
a następnie usuwa źródło.shutil.copy2()
nie można skopiować wszystkich metadanych pliku , więc jeśli tak się stanie, to tak, jakby to zrobić,cp -p
a następnierm
, jak się okazuje,W przypadku nazwy os.rename lub shutil.move musisz zaimportować moduł. Do przeniesienia wszystkich plików nie jest wymagany znak *.
Mamy folder w / opt / awesome o nazwie source z jednym plikiem o nazwie awesome.txt.
Użyliśmy os.listdir, aby zobaczyć, że nazwa folderu faktycznie się zmieniła. Oto shutil przenoszący cel z powrotem do źródła.
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.
źródło
Po Pythonie 3.4 możesz także użyć
pathlib
klasy,Path
aby przenieść plik.https://docs.python.org/3.4/library/pathlib.html#pathlib.Path.rename
źródło
Z tego właśnie korzystam:
Teraz w pełni funkcjonalny. Mam nadzieję, że to ci pomoże.
Edytować:
Przekształciłem to w funkcję, która akceptuje katalog źródłowy i docelowy, tworząc folder docelowy, jeśli nie istnieje, i przenosi pliki. Pozwala również na filtrowanie plików src, na przykład jeśli chcesz tylko przenosić obrazy, następnie używasz wzorca
'*.jpg'
, domyślnie przenosi wszystko w kataloguźródło
os.path.join(parent_path, filename)
zamiast konkatenacji łańcuchów, aby uniknąć problemów międzyplatformowychPrzyjęta odpowiedź nie jest prawidłowa, ponieważ pytanie nie dotyczy zmiany nazwy pliku na plik, ale przeniesienie wielu plików do katalogu.
shutil.move
wykona pracę, ale w tym celuos.rename
jest bezużyteczny (jak podano w komentarzach), ponieważ miejsce docelowe musi mieć jawną nazwę pliku.źródło
os.path.basename(my_file_path)
i katalogi plików za pomocąos.path.dirname(my_file_path)
. Ponadto OP nie wyjaśnił, czy chce przenieść wiele plików. Wspomniał o przeniesieniu tylko jednego pliku w pytaniu, ale jego przykładowy kod sugerował przeniesienie wielu plików.W oparciu o opisaną tutaj odpowiedź użycie
subprocess
to kolejna opcja.Coś takiego:
Jestem ciekawy, jakie są zalety i wady tej metody w porównaniu do
shutil
. Ponieważ w moim przypadku używam jużsubprocess
z innych powodów i wydaje się, że działa, jestem skłonny się z tym trzymać.Czy może zależy to od systemu?
źródło
mv
był używany z powodzeniem w systemie operacyjnym Windows.Jest to rozwiązanie, które nie umożliwia
shell
korzystaniamv
.źródło
inny dysk np. C: -> D:
źródło
f"{new_path}{f}"
ale biorąc pod uwagę, że nie masz statycznego tekstu w ciągu, może to być więcej pracy ... Próbowałem przyzwyczaić się do używania f-stringi.