0

I have a text file with hundreds of lines, each line contains a number to represent the level the folder/file should be on and a folder/file name. Because the hierarchy is too large I want to make a script to automate making this directory/sub directory.

Example text file

 .0.  Folder Name a  
  .1. Folder Name b  
   .2. Folder Name c  
   .2. Folder Name c2  
  .1. Folder Name d  
   .2. Folder Name e  
   .2. Folder Name e2  
    .3. Folder Name f  

I assume I need to read line by line and use os.mkdir, but I don't know how to step down a directory level.

#path of file
import os

with open('Tree.txt', 'r') as t:
 for line in t:
  readline(.{Level}. {FolderName})
    if Level == '0'
     os.mkdir(FolderName)
    else if Level == '1'
     # go down and os.mkdir(FolderName)
3
  • 1
    can you provide a tree structue of the folder created based on the text file Commented May 27, 2019 at 5:37
  • 1
    Welcome to StackOverflow! Have you read this. What you have tried? Please read How to create a Minimal, Reproducible Example Commented May 27, 2019 at 5:38
  • You won't need to explicitly 'step down a directory level' since the path you pass to os.mkdir has that information. If folder a is /home/a, then b would be /home/a/b, and it is created at the desired level. Commented May 27, 2019 at 5:48

5 Answers 5

1

You can use os.mkdir(path) to create a directory.

You can also use the following regex to parse your string:

"\.(\d+)\. Folder Name ([a-zA-Z\d]+)"

Then you can use recursion to create the directory tree:

import os
import re

regex = r"\.([\d+])\. Folder Name ([a-zA-Z\d]+)"


def create_dir_tree(dir_list, current_level, current_path):
    for idx, line in enumerate(dir_list):
        matcher = re.match(regex, line)
        if not matcher:
            return
        level = int(matcher.group(1))
        dir_name = matcher.group(2)

        if level <= current_level:
            return
        if level != current_level + 1:
            continue

        new_path = os.path.join(current_path, dir_name)
        os.mkdir(new_path)

        create_dir_tree(dir_list[idx + 1:], level, new_path)


list = [".0. Folder Name a",
        ".1. Folder Name b",
        ".2. Folder Name c",
        ".2. Folder Name c2",
        ".1. Folder Name d",
        ".2. Folder Name e",
        ".2. Folder Name e2",
        ".3. Folder Name f"]

create_dir_tree(list, -1, os.path.expanduser("~/Desktop/untitled folder"))

Now it's only a matter of reading the file to a list

Sign up to request clarification or add additional context in comments.

Comments

0

To step down and step up a directory you can use os.chdir('example filepath') and os.chdir('..')

Comments

0

I did something like this. It is using os.mkdir and os.chdir, inspired from @JROS.

It basically checks by levels, if level is bigger it gets inside the folder. If it is less, then it simply moves back n times, n being the difference between two consecutive levels.

commands.txt is the file that contains the lines.

import os

with open('commands.txt') as f:
  line = f.readline().strip()
  prev_level = int(line.split(". ")[0].split(".")[1])
  folder_name = line.split("Folder Name ")[1]
  curr_level = prev_level
  while line:
    if curr_level > prev_level:
      os.chdir(prev_folder_name)
    elif curr_level < prev_level:
      diff = prev_level - curr_level
      for i in range(diff):
        os.chdir('..')

    os.mkdir(folder_name)

    line = f.readline().strip()
    if line:
      prev_level = curr_level
      curr_level = int(line.split(". ")[0].split(".")[1])
      prev_folder_name = folder_name
      folder_name = line.split("Folder Name ")[1]

Comments

0

It seems that you just want to: os.system(f'mkdir -p {FolderName}')

Comments

0

For clarity I do not show reading of file, but hard-code it, so say you use variable content to store what was read from file:

content = ''' .0.  Folder Name a  
  .1. Folder Name b  
   .2. Folder Name c  
   .2. Folder Name c2  
  .1. Folder Name d  
   .2. Folder Name e  
   .2. Folder Name e2  
    .3. Folder Name f  '''

You could break it into lines:

content = content.split('\n')

Now it is list of lines, but these lines have spaces in front and end, which we need to remove:

content = [i.strip(' ') for i in content]

Now is time to tokenize it

def tokenize(x):
    n,name = x.split(' Folder Name ',1)
    return (int(n.replace('.','')),name)
content = [tokenize(i) for i in content]

Now print(content) gives [(0, 'a'), (1, 'b'), (2, 'c'), (2, 'c2'), (1, 'd'), (2, 'e'), (2, 'e2'), (3, 'f')] that is list of tuples (int,str).

Finally we could do traversal of tree:

import os
paths = []
while(content):
    path = [content[0]]
    for i in content[1:]:
        if(i[0]<=path[-1][0]):
            break
        path.append(i)
    paths.append(os.path.join(*[i[1] for i in path]))
    content.remove(path[-1])

Now my paths is ['a/b/c', 'a/b/c2', 'a/b', 'a/d/e', 'a/d/e2/f', 'a/d/e2', 'a/d', 'a'] as I use Linux OS and os.path.join will use proper slashes for your system. Explanation of above code: I traverse this tree and when I go into deadend I add path which lead to it to my list paths and remove that leaf (list remove always removes only 1 element so no need to worry about deleting same named folder being another leaf). I end when all leafs are deleted (hope that you could understand, sadly I am unable to explain it in more clear way)

As paths is now list of paths I could simply use os.makedirs() function. Note that if you would try to make dir which already exist it would result in error, so we need to check firstly if it does not exist:

for i in paths:
    if not os.path.exists(i):
        os.makedirs(i)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.