vobject
vobject

Reputation: 5310

Python - Get relative path of all files and subfolders in a directory

I am searching for a good way to get relative paths of files and (sub)folders within a specific folder.

For my current approach I am using os.walk(). It is working but it does not seem "pythonic" to me:

myFolder = "myfolder"
fileSet = set() # yes, I need a set()

for root, dirs, files in os.walk(myFolder):
    for fileName in files:
        fileSet.add(root.replace(myFolder, "") + os.sep + fileName)

Any other suggestions?

Thanks

Upvotes: 54

Views: 79158

Answers (8)

andyhasit
andyhasit

Reputation: 15349

The accepted answer gives you paths with a dot prefix like ./package.json which may not be what you want.

This way doesn't do that:

for dirpath, dirnames, filenames in os.walk(root_dir):
    for name in filenames:
        full = os.path.join(dirpath, name)
        rel = os.path.relpath(full, root_dir)

Upvotes: 0

Newtonx
Newtonx

Reputation: 3675

Use os.path.relpath(). This is exactly its intended use.

import os
root_dir = "myfolder"
file_set = set()

for dir_, _, files in os.walk(root_dir):
    for file_name in files:
        rel_dir = os.path.relpath(dir_, root_dir)
        rel_file = os.path.join(rel_dir, file_name)
        file_set.add(rel_file)

Note that os.path.relpath() was added in Python 2.6 and is supported on Windows and Unix.

Upvotes: 99

Bart77
Bart77

Reputation: 103

I did it like this:

import pathlib

def find_path_to_file(file_name):
    globa_path = pathlib.Path.home()
    for path in sorted(globa_path.rglob('*')):
            if str(file_name) in str(path):
                return str(path)

Upvotes: 0

S.Lott
S.Lott

Reputation: 392050

myFolder = "myfolder"
fileSet = set() 

for root, dirs, files in os.walk(myFolder):
    for fileName in files:
        fileSet.add( os.path.join( root[len(myFolder):], fileName ))

Upvotes: 11

user147995
user147995

Reputation: 11

You can also use os.listdir() if you are just searching for an alternative to your solution.

But basically the logic will stay the same: iterate over the files - if directory, iterate through the subdirectory.

Upvotes: 1

sunqiang
sunqiang

Reputation: 6492

I think os.walk is the right choice here.
maybe root.replace(myFolder, "") should change to root.replace(myFolder, "", 1) to avoid potential sth. you know.
If you already get the files and (sub)folders, os.path.commonprefix worth a look too.

Upvotes: 3

Anurag Uniyal
Anurag Uniyal

Reputation: 88855

What you are doing is perfectly right and I think should be done that way, BUT just for the sake of alternative, here is an attempt

import os

def getFiles(myFolder):
    old = os.getcwd()
    os.chdir(myFolder)

    fileSet = set()

    for root, dirs, files in os.walk(""):
        for f in files:
            fileSet.add(os.path.join(root, f))

    os.chdir(old)
    return fileSet

Upvotes: 3

jkp
jkp

Reputation: 81330

Thats probably the best way to be honest: you can use glob to go a certain number of layers down, but if you need it to be recursive you have to walk.

Upvotes: 2

Related Questions