I'm trying to move the files from one source directory to another destination directory considering the destination directory has the same file and folder structure as the source directory.
source directory:
source/
├── file1
├── file2
├── file3
├── folder_a
└── folder_b
├── file1
├── file2
└── file3
destination directory:
destination/
├── file4
├── file5
├── file6
├── folder_a
└── folder_b
├── file4
├── file5
└── file6
The script i'm trying to create:
import os
import shutil
from subprocess import check_output
os.chdir("/home/smetro/source/")
destination= "/home/smetro/Games/destination"
def mover(destination):
for i in os.listdir():
if os.path.isfile(i):
shutil.copy(i,destination)
print("file moved: {} to {}".format(i,destination))
else:
new_dir= check_output('pwd').strip().decode('utf-8')+"/"+i
os.chdir(new_dir)
destination += "/{}".format(i)
mover(destination)
mover(destination)
whenever I'm running the script I'm able to move some files from source directory to destination directory. However, it throws FileNotFoundError
error and I get the output as mentioned below:
file moved: file1 to /home/smetro/Games/destination
file moved: file3 to /home/smetro/Games/destination
file moved: file2 to /home/smetro/Games/destination
file moved: file1 to /home/smetro/Games/destination/folder_b
file moved: file3 to /home/smetro/Games/destination/folder_b
file moved: file2 to /home/smetro/Games/destination/folder_b
Traceback (most recent call last):
File "/home/smetro/move.py", line 18, in <module>
mover(destination)
File "/home/smetro/move.py", line 14, in mover
os.chdir(new_dir)
FileNotFoundError: [Errno 2] No such file or directory: '/home/smetro/source/folder_b/folder_a'
I'm not sure if I'm using the recursion in a wrong way or not able to use the OS module properly. Any help would be much appreciated.
The issue has nothing to do with recursion. The traceback shows you that the error didn't occur in a recursive call. It also has nothing to do with the os
module.
The best hint is the path of the nonexistent directory: folder_b/folder_a
. The issue is that you're looping over os.listdir()
, but changing the working directory in the loop, so after cd-ing into folder_b
, it tries to cd into folder_a
, which isn't in folder_b
.
I can think of a few different ways to fix that, but you'd probably be better off not changing the working directory at all. Instead, use os.walk()
to walk the directory branch for you, as well as pathlib
to simplify working with paths. To get you started:
from pathlib import Path
source = Path("/home/smetro/source/")
destination = Path("/home/smetro/Games/destination")
for root, _dirs, files in os.walk(source):
root_rel = Path(root).relative_to(source)
new_root = destination / root_rel
for file in files:
print(new_root / file) # Just for demo