Копирование файлов с помощью Python с полной структурой папок

Nov 30 2020

Я заменяю свой SSD на лучший через несколько дней, и на нем хранится куча данных, о которых я мог бы пожалеть, если бы удалил. Единственный тип файлов, которые мне нужны, - это файлы PDF, файлы docx, файлы txt и другие вещи. Итак, я написал сценарий для поиска этих файлов с помощью python.

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

Этот сценарий просто находит файл с форматами, соответствующими списку FileExt, и записывает эти местоположения в файл test.txt. Теперь мне нужно передать эти файлы, сохранив точную структуру каталогов. Например, если есть файл как

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

Скрипт должен скопировать всю структуру каталогов как

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

Как мне копировать, используя эту точную структуру.
TL; DR: необходимо копировать файлы, сохраняя структуру каталогов, как при использовании Python
PS Я использую Windows с Python 3.8

Ответы

FloLie Nov 29 2020 at 23:20

Для каждой строки в списке файлов выполните следующие действия:

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

Поскольку вы можете записывать данные в файл, я предполагаю, что вы также знаете, как читать данные из этого файла. Затем для каждой строки (скажем, вызовите ее sourceв этом файле, используйте shutil.copyfile(source, dest).

Вы можете создать destстроку, манипулируя source:

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

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

Как упоминалось в комментариях, путь назначения не будет создан автоматически, но его можно обрабатывать, как описано здесь: создать путь назначения для файлов shutil.copy

CrYbAbY Nov 29 2020 at 23:54

Спасибо @Emmo и @FloLie за их ответы. Мне просто пришлось использовать функцию os.makedirs () с флагом exist_ok, установленным в true для каждого файла в списке.

Этот код помещается сразу после кода в вопросе.

#######################################
# 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 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 Этот ответ предназначен только для таких людей, как я, которые иногда не могут понять небольшие фрагменты вне контекста 😁