Moving Files from directory to their own folders

86 views Asked by At

I am struggling with the paths and directories to solve this problem. Basically, I have a long list of .lammps files in one directory. My goal is to copy each file and move it into its own folder (which is one directory back) where its folder name is the file name minus the .lammps. All of the folders are already made, I just can't seem to figure out moving them. The entire list of files is in the Files directory. The individual folders are in the ROTATED FILES directory. Here is what I have. Any tips greatly appreciated.

Here is a file example n-optimized.new.10_10-90-10_10.Ni00Nj01.lammps

The folder for this file is then named n-optimized.new.10_10-90-10_10.Ni00Nj01

import os

file_directory = os.chdir("C:\Py Practice\ROTATED FILES\Files")
files = os.listdir()
for file in files:

    # get the file -.lammps string
    name1 = file.split('.')[0:4]
    name2 = ".".join(name1)
    
    # get the path for the files new respective folder (back a directory and paste folder name)
    file_folder = "C:\Py Practice\ROTATED FILES/" + name2
    
    # Move
    combined_path = os.path.join(file, file_folder)

I've tried shutil and figured path join might be easier.

1

There are 1 answers

0
NotAName On

First of all, the code you have here shouldn't work since you either have to escape backslashes or use a raw string. Secondly, rather than using os for file system operations, it's much better to learn how to use pathlib (also a core python module) which provides a more modern object-oriented approach to file operations.

Using pathlib and shutil you can do something like

from pathlib import Path
from shutil import copyfile

file_directory = Path(r"C:\Py Practice\ROTATED FILES\Files")

# get the list of source files
source_files = [f for f in file_directory.glob('*.lammps')]

# create target file paths
target_files = [file_directory.parent / f.stem/ f.name for f in source_files]

for source, target in zip(source_files, target_files):
    copyfile(str(source), str(target))

Here we're accessing different parts of file path using a convenient OOP structure. For example, if your file f is located in 'c:/foo/bar/boo.txt' then f.name is just the name of file: boo.txt, f.stem is the stem part of the file name (excluding the extension) boo, f.parent is its parent directory 'c:/foo/bar/' etc.

There's a really handy graphic of pathlib Path objects here.

The only inconvenience is that not all of core modules support Path objects yet so for copyfile we just need to get the string representation by calling str on the object.

And you don't even need to have target folders created beforehand, it's very easy to create the necessary folder structure as you go along:

from pathlib import Path
from shutil import copyfile

file_directory = Path(r"C:\Py Practice\ROTATED FILES\Files")

# get the list of source files
source_files = [f for f in file_directory.glob('*.lammps')]

# create target file paths
target_files = [file_directory.parent / f.stem/ f.name for f in source_files]

for source, target in zip(source_files, target_files):
    # check that target directory exists
    # and create a folder if not
    if not target.parent.is_dir():
        target.parent.mkdir()
    copyfile(str(source), str(target))