Skopiuj pliki za pomocą Pythona z pełną strukturą folderów

Nov 30 2020

Zmieniam dysk SSD na lepszy za kilka dni i mam na nim sporo danych, których mógłbym żałować, gdyby zostały usunięte. Jedyne typy plików, których potrzebuję, to pliki PDF, pliki docx, pliki txt i inne rzeczy. Więc napisałem skrypt, aby zlokalizować te pliki za pomocą Pythona.

# to copy all of my documents into another location.
import sys
import os
import time
import pathlib
import json


filePath=["D:\\", "C:\\Users"]
# ext=['mkv','docx','doc','pdf','mp4','zip',]
fileExt=["**\*.docx","**\*.doc","**\*.pdf"]
fileList={}
for each_drive in filePath:
    fileList[each_drive]={}
    for each_type in fileExt:
        fileList[each_drive][each_type]=list(pathlib.Path(each_drive).glob(each_type))

file1 = open('test.txt', 'w')
for each in fileList.values():
    for each2 in each.values():
        for entry in each2:
            print(entry)
            file1.writelines(str(str(entry)+ "\n"))


file1.close()

Ten skrypt po prostu lokalizuje plik z formatami pasującymi do listy FileExt i zapisuje te lokalizacje do pliku test.txt. Teraz muszę przenieść te pliki, zachowując dokładną strukturę katalogów. Na przykład jeśli istnieje plik z rozszerzeniem

C:\Users\<MyUser>\AppData\Local\Files\S0\1\Attachments\hpe[4].docx

Skrypt powinien skopiować całą strukturę katalogów jako

<BackupDrive>:\<BackupFolderName>\C\Users\<MyUser>\AppData\Local\Files\S0\1\Attachments\hpe[4].docx

Jak skopiować przy użyciu tej dokładnej struktury.
TLDR: Muszę skopiować pliki, zachowując strukturę katalogów, tak jak w przypadku Python
PS Używam systemu Windows z Pythonem 3.8

Odpowiedzi

FloLie Nov 29 2020 at 23:20

Dla każdego wiersza na liście plików wykonaj następujące czynności:

for filePath in fileList:
    destination = .join(['<BackupDrive>:\<BackupFolderName>', filePath[2:]])
    os.makedirs(os.path.dirname(filePath), exist_ok=True)
    shutil.copy(filePath , destination)
emmo Nov 29 2020 at 23:12

Ponieważ możesz zapisywać dane do pliku, zakładam, że wiesz również, jak odczytywać dane z tego pliku. Następnie dla każdej linii (powiedzmy, że wywołaj ją sourcew tym pliku, użyj shutil.copyfile(source, dest).

Możesz utworzyć destciąg, manipulując source:

# remove 'C:'
str_split = source[2:]

# add backup drive and folder
dest = ''.join(['<BackupDrive>:\<BackupFolderName>', str_split])

Jak wspomniano w komentarzach, ścieżka docelowa nie zostanie utworzona automatycznie, ale można ją obsługiwać tak, jak wyjaśniono tutaj: utwórz ścieżkę docelową dla plików shutil.copy

CrYbAbY Nov 29 2020 at 23:54

Dzięki @Emmo i @FloLie za ich odpowiedzi. Po prostu musiałem użyć funkcji os.makedirs () z flagą exist_ok ustawioną na true dla każdego pliku na liście.

To jest kod umieszczony bezpośrednio po kodzie w pytaniu.

#######################################
# create destination directory
file1=open ('test.txt', 'r')
text= file1.readlines()
# print(text)
for each in text:
    each=each[:-1]
    destination="BackupDIR-"+each[0]+each[2:]
    os.makedirs(os.path.dirname(destination), exist_ok=True)
    shutil.copy(each,destination)

To sprawia, że ​​cały kod wygląda następująco:

# to copy all of my documents into another location.
import os
import time
import pathlib
import json
import shutil


filePath=["D:\\", "C:\\Users"]
# ext=['mkv','docx','doc','pdf','mp4','zip',]
fileExt=["**\*.docx","**\*.doc","**\*.pdf"]
fileList={}
for each_drive in filePath:
    fileList[each_drive]={}
    for each_type in fileExt:
        fileList[each_drive][each_type]=list(pathlib.Path(each_drive).glob(each_type))

file1 = open('test.txt', 'w')
for each in fileList.values():
    for each2 in each.values():
        for entry in each2:
            print(entry)
            file1.writelines(str(str(entry)+ "\n"))
file1.close()

#######################################
# create destination directory
file1=open ('test.txt', 'r')
text= file1.readlines()
# print(text)
for each in text:
    each=each[:-1]
    destination="BackupDIR-"+each[0]+each[2:]
    os.makedirs(os.path.dirname(destination), exist_ok=True)
    shutil.copy(each,destination)

PS Ta odpowiedź jest tylko dla ludzi takich jak ja, którzy czasami nie potrafią zrozumieć małych fragmentów z kontekstu 😁