Loop control when creating directories

1.8k views Asked by At

I asked the question before but it wasn't clear, I ll try this time to make it more clear. i am creating 66 directories, each directory has 19 sub-directories, inside those 19 (all will be named 1-19) sub-directories i am moving three files, two files are arbitrary the third file has data relying on the loop that it is, 4th loop will create a directory 4/ and contain a specific file that has 4 inside, etc.. I am trying to use break, continue statements to control the looping so that only one directory is created but 19 subdirectories are created with the correct data in that file, the name of the name of that file MUST be the same in every directory so I have to move them immediately during the loop so the data inside does not get overwritten , since I have everything in a for loop ranging from 1 to 20, it keeps on trying to create another main directory and it is saying that I already have created, here is the code I have:

base_direct = '{}/'.format(dir_Name) #create the main directories so they are already there,

for x in range(1,20): #loop to create 19 subdirectories 
        if not os.path.exists(str(x)+'/'):os.mkdir(str(x)+'/') #create directories 1/ 2/ 3/ etc..
        else: continue
        shutil.copy(filename, str(x)) #copy file to the directories
        shutil.copy(filename1, str(x)) #copy second file
        frag = open("fragments_procs.in", 'w') #open a new file
        frag.write(str(x) + "\n" + str(20-x)) #file will read 1, 19, since it is on first loop and must be in 1/, second file will read 2 18 must be in 2/ etc...
        shutil.copy("fragments_procs.in", str(x)) #copy the input file into the numbered directory
        shutil.move(str(x), '{}/'.format(dir_Name)) #move 1/ -> /dir_Name
        if not os.path.exists('{}/'.format(dir_Name)+str(x)):shutil.move(str(x), '{}/'.format(dir_Name)) #if dir_name/1/ exists continue to making dir_Name/2/
        else: continue


genFiles(dir_Name, filename, filenam1)
genfiles("Water-Water", "Water1", "Water0")

code is working and creating Water-Water/, but stops there and says Water-Water/1/ already exists

loop code:

fileName = os.path.splitext(xyzfile)[0]
 for x in range(1,20):
     path = os.path.join(fileName, str(x))
     try:
         os.makedirs(path)
     except OSError as exception:
         if exception.errno != errno.EEXIST:
             raise

     shutil.copy(filename, os.path.join(path, filename))
     shutil.copy(filename1, os.path.join(path, filename1))
     with open(os.path.join(path, "fragments_procs.in"), 'w') as frag:
         frag.write(str(x) + "\n" +str(20-x))
             frag.flush()
             frag.close()

         subprocess.Popen(["sbatch", "/work/jobfile_fde", fileName,     "2"], cwd=path)
2

There are 2 answers

15
tdelaney On BEST ANSWER

You have several problems including not creating destination paths correctly and trying to write to the directory name instead of a file. Try using os.path instead of cooking up your own strings, it makes the program less confusing!

for x in range(1,20): #loop to create 19 subdirectories
    path = os.path.join(dir_Name, str(x)) 
    os.makedirs(path, exist_ok=True) #create directories 1/ 2/ 3/ etc..
    shutil.copy(filename, os.path.join(path, filename))
    shutil.copy(filename1, os.path.join(path, filename1))
    with open(os.path.join(path, "fragments_procs.in"), 'w') as frag:
        frag.write(str(x) + "\n" + str(20-x)) #file will read 1, 19, since it is on first loop and must be in 1/, second file will read 2 18 must be in 2/ etc...
4
abarnert On

While there seem to be multiple possible problems with your code (e.g., you never close the file, or even flush it, and yet you're trying to copy it, meaning you could easily get incomplete files, empty files, or even locking errors), I think the one you're asking about can be answered in one word: makedirs:

since I have everything in a for loop ranging from 1 to 20, it keeps on trying to create another main directory and it is saying that I already have created

If you call os.makedirs('foo/bar/baz', exist_ok=True), that will create foo if and only if it doesn't exist, then create foo/bar if and only if it doesn't exist, then create foo/bar/baz if and only if it doesn't exist. Whether all 3 exist, just the first 2, or none of them, you'll get no error.

In Python 3.1 and early (including 2.7), there is no exist_ok parameter. But you will only get an error if all 3 directories exist; the fact that, e.g., foo/bar already exists is still fine.