pythonshutilpython-os

PermissionError: [Errno 13] Permission denied. How can I rewrite a code to place a folder "a" which is in folder "b" to folder "c"


def tdata_move():
    number_of_acc = len([file for file in os.scandir(fr"D:\tdata for accs")])
    for item in range(0, number_of_acc):
        for folder in os.listdir(r"D:\tdata for accs"):
            shutil.copyfile(fr"D:\tdata for accs\{folder}", fr"D:\accs_test\acc{item + 1}")

Error:

PermissionError: [Errno 13] Permission denied: 'D:\\data for accs\\068686868'

So here I'm trying to make a loop, that takes folder "a" which is located in folder "b", and puts it to folder "c". Looks like that:

acc1 should store "data" folder from folder "D:\data for accs\068686868\data"
acc2 should store "data" folder from folder "D:\data for accs\049193193\data"
acc3 should store "data" folder from folder "D:\data for accs\318418317\data"

But I received:

PermissionError: [Errno 13] Permission denied: 'D:\data for accs \

So right now it can't read data from 068686868 folder, no permission.


Solution

  • The permission error is from using copyfile. Use copytree for directories:

    import os
    import glob
    import shutil
    
    original = 'org'
    destination = 'dest'
    
    # Generates paths to directories only with */
    for num, item in enumerate(glob.glob(os.path.join(original, '*/')), start=1):
        target = os.path.join(destination, f'acc{num}')
        print(f'Copying {item} to {target}...')
        shutil.copytree(item, target)
    

    Given a directory tree of:

    ───org
        │   file4.txt
        ├───1
        │       file1.txt
        ├───2
        │       file2.txt
        └───3
                file3.txt
    

    All but file4.txt, which is not in a directory, will be copied to dest:

    Copying org\1\ to dest\acc1...
    Copying org\2\ to dest\acc2...
    Copying org\3\ to dest\acc3...
    

    Ending tree:

    ├───dest
    │   ├───acc1
    │   │       file1.txt
    │   ├───acc2
    │   │       file2.txt
    │   └───acc3
    │           file3.txt
    └───org
        │   file4.txt
        ├───1
        │       file1.txt
        ├───2
        │       file2.txt
        └───3
                file3.txt
    

    Here also is a pathlib version (available in Python 3.4+). It is a cleaner interface to iterating files and directories:

    import os
    import shutil
    from pathlib import Path
    
    original = Path('org')
    destination = Path('dest')
    
    for num, item in enumerate(original.glob('*/'), start=1):
        target = destination / f'acc{num}'
        print(f'Copying {item} to {target}...')
        shutil.copytree(item, target)