Reputation: 5310
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
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
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
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
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
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
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
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
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