ah bon
ah bon

Reputation: 10011

Move files from sepecific subdirectories to another based on names in Python

Given a directory ./ and its subdirectories ('project1, project2, project3, ...') and files structure as follows:

├── project1
│   ├── file1
│   ├── file2
│   ├── process
│   │   └── f1
│   │       ├── pic1.png
│   │       └── pic2.jpg
│   ├── progress
│   │   └── f2
│   │       ├── 623.jpg
│   │       └── pic2323.png
│   └── session
│       └── f3
│           ├── 5632116.jpg
│           └── 72163.png
└── project2
    ├── file1
    ├── file2
    ├── process
    │   └── f1
    │       ├── pic1.png
    │       └── pic2.jpg
    ├── progress
    │   └── f2
    │       ├── 623.jpg
    │       └── pic2323.png
    └── session
        └── f3
            ├── 5632116.jpg
            └── 72163.png

For each project folder, I need to move pictures from process to empty files1, from progress and session to empty files2.

The expected result will like this:

|── project1
|   ├── file1
|   │     ├── pic1.png
|   │     └── pic2.jpg
|   |── file2
|         ├── 623.jpg
|         └── pic2323.png
|         ├── 5632116.jpg
|         └── 72163.png
└── project2
    ├── file1
    │     ├── pic1.png
    │     └── pic2.jpg
    |── file2
          ├── 623.jpg
          └── pic2323.png
          ├── 5632116.jpg
          └── 72163.png

My trial code works, but I don't think it's concise enough, welcome to improve it:

base_dir = './'
src_dst_map = {
   'session': 'files1',
   'process': 'files2',
   'progress': 'files2'
}

for child in os.listdir(base_dir):
    # print(child)
    child_path = os.path.join(base_dir, child)
    # print(child_path)
    # src_path = os.path.join(child_path, 'session')
    # print(src_path)
    for src, dst in src_dst_map.items():
        # print(src)
        src_path = os.path.join(child_path, src)
        dst_path = os.path.join(child_path, dst)
        print(src_path)
        print(dst_path)
        for root, dirs, files in os.walk(src_path):
            # print(root)
            for file in files:
                # print(file)
                srce_path = os.path.join(root, file)
                print(srce_path)
                shutil.move(srce_path, dst_path)
        shutil.rmtree(src_path, ignore_errors = True)

Upvotes: 0

Views: 48

Answers (1)

Jakob
Jakob

Reputation: 246

To be honest, this is already quite concise and it does the job, so I would not bother too much about changing it. Your code runs in 10 lines (plus set up of the dictionary and base path).

Regarding the duplicated images, you could check for existance of file in dst_path, and if it is present, add a prefix (or suffix) to the dublicated file.

In the following, the prefix according to the source is added, until a unique file name is found. This also catches, if there are more than one dublicate of the same file in one subfolder. You could change this according to your specific needs, but it should give you the general idea.

...

    for root, dirs, files in os.walk(src_path):
        for file in files:
            srce_path = os.path.join(root, file)
            while os.path.isfile(os.path.join(dst_path, file)):
                file = '_'.join([src, file])
            shutil.move(srce_path, os.path.join(dst_path, file))

I opted for a prefix, as this is much simpler to implement. A suffix would have to be added between the filename and the file ending, this would require a bit of additional code.

Upvotes: 1

Related Questions