Copie archivos usando python con una estructura de carpetas completa

Nov 30 2020

Voy a cambiar mi SSD por uno mejor en unos pocos días y tengo un montón de datos almacenados que podría lamentar si se eliminan. El único tipo de archivos que necesito son archivos PDF, archivos docx, archivos txt y otras cosas. Entonces, escribí un script para ubicar esos archivos usando 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()

Este script solo ubica el archivo con formatos que coinciden con la lista FileExt y escribe esas ubicaciones en el archivo test.txt. Ahora necesito transferir estos archivos manteniendo la estructura exacta del directorio. Por ejemplo, si hay un archivo como

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

El script debe copiar toda la estructura del directorio como

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

¿Cómo copio usando esta estructura exacta?
TLDR: Necesito copiar archivos mientras se mantiene la estructura de directorios como está usando Python
PS Estoy usando Windows, con Python 3.8

Respuestas

FloLie Nov 29 2020 at 23:20

Para cada línea de su lista de archivos, haga lo siguiente:

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

Dado que puede escribir datos en un archivo, supongo que también sabe cómo leer los datos de ese archivo. Luego, para cada línea (digamos llamarlo sourceen ese archivo, use shutil.copyfile(source, dest).

Puede crear la destcadena manipulando source:

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

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

Como se menciona en los comentarios, la ruta de destino no se creará automáticamente, pero se puede manejar como se explica aquí: crear ruta de destino para archivos shutil.copy

CrYbAbY Nov 29 2020 at 23:54

Gracias a @Emmo y @FloLie por sus respuestas. Solo tuve que usar la función os.makedirs () con el indicador exist_ok establecido en verdadero para cada archivo en la lista.

Este es el código que se coloca inmediatamente después del código de la pregunta.

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

Esto hace que todo el código se vea así:

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

PD: Esta respuesta solo está aquí para personas como yo, que a veces no pueden entender pequeños fragmentos fuera de contexto