Spoobars
Spoobars

Reputation: 11

Finding the "root" of a directory

I am attempting to write a function in python that scans the contents of a directory at the script's level (once de-bugged I'll switch it to not needing to be at the same level but for this problem it's irrelevant) and recursively lists the paths to anything that is not a directory. The logic I am working with is:

If the parent "directory" is not a directory then it must be a file so print the path to it. Otherwise, for every "file" in that directory, if each "file" is not actually a directory, state the path to the file, and if the "file" is actually a directory, call the function again.

The environment I am using is as follows: I have the script at the same level as a directory named a, and inside a is a file d.txt, as well as another directory named b. Inside b is a file c.text. Per the way I would like this function to execute, first it should recognize that a is in fact a directory, and therefore begin to iterate over its contents. When it encounters d.txt, it should print out the path to it, and then when it encounters directory b it should begin to iterate over it's contents and thereby print the path to c.txt when it sees it. So in this example, the output of the script should be "C:\private\a\d.txt, C:\private\a\b\c.txt" but instead it is "C:\private\d.txt, C:\private\b". Here is the code thus far:

import os

def find_root(directory):
    if not os.path.isdir(directory):
        print(os.path.abspath(directory))
    else:
        for file in os.listdir(directory):
            if not os.path.isdir(file):
                print(os.path.abspath(file))
            else:
                find_root(file)

find_root('a')

Upvotes: 0

Views: 114

Answers (1)

CristiFati
CristiFati

Reputation: 41137

[Python]: os.listdir(path='.'):

Return a list containing the names of the entries in the directory given by path.

but they are just basenames. So, in order for them to make sense, when you go a level deeper in the recursion either:

  1. Prepend the "current" folder to their name
  2. cd to each folder (and also, cd back when returning from recursion)

Here's your code modified to use the 1st approach:

import os

def find_root(path):
    if os.path.isdir(path):
        for item in os.listdir(path):
            full_item = os.path.join(path, item)
            if os.path.isdir(full_item):
                find_root(full_item)
            else:
                print(os.path.abspath(full_item))
    else:
        print(os.path.abspath(path))


if __name__ == "__main__":
    find_root("a")

Notes:

  • I recreated your folder structure
  • I renamed some of the variables for clarity
  • I reversed the negate conditions

Output:

c:\Work\Dev\StackOverflow\q47193260>"c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" a.py
c:\Work\Dev\StackOverflow\q47193260\a\b\c.txt
c:\Work\Dev\StackOverflow\q47193260\a\d.txt

Upvotes: 2

Related Questions