Reputation: 11804
I have a file at location a/b/c/d/e/f/x.xml
. i need to find the absolute path of the the dir d
, i.e a parent dir up the hierarchy that matches the dir name d
.
I can obtain the filename's current dir as os.path.abspath(__file__)
. i have see the documentation for pathlib and glob, but am unable to figure out how would i use them.
Can someone help
EDIT:
Thanks to all the answers below, I have gotten to a one liner
os.path.join(*list(itertools.takewhile(lambda x: x != 'd', pathlib.PurePath(os.getcwd()).parts)))
I also need to append the actual dir name to it, i.e, the output should be a/b/c/d
. An ugly solution is below (uses os.path.join twice). Can someone fix it (by adding an element to the iterator or to the list in one line :)
os.path.join(os.path.join(*list(itertools.takewhile(lambda x: x != 'd', pathlib.PurePath(os.getcwd()).parts))),"d")
Upvotes: 1
Views: 1591
Reputation: 11804
I found the one-liner finally:
os.path.join(*list(itertools.takewhile(lambda x: x != 'd', pathlib.PurePath(os.getcwd()).parts)),"d")
wouldnt hve been possible without others answers though. thanks a lot.
Upvotes: 0
Reputation: 150178
You can use pathlib
's Path.resolve()
and Path.parents
:
from pathlib import Path
path = Path("a/b/c/d/e/f/x.xml").resolve()
for parent in path.parents:
if parent.name == "d": # if the final component is "d", the dir is found
print(parent)
break
Upvotes: 2
Reputation: 149185
Assuming you have a file in your current dir, you can get it absolute path (starting at root) with abspath
:
path = os.path.abspath(filename)
Thes the magic word is os.path.split
that splits a pathname into the last component and the head (everything in front of it). So to get the absolute path of what comes before d
just iterate the components:
def findinit(path, comp):
while (len(path) > 1):
t = os.path.split(path)
if t[1] == comp:
return t[0]
path = t[0]
return None
You can control that findinit('/a/b/c/d/e/f/x.xml')
gives as expected /a/b/c
Alternatively if you want to use the pathlib
module, you can search the parts
for a specific component:
def findinit(path, comp):
p = pathlib.PurePath(path)
i = p.parts.index(comp)
if i != -1:
return pathlib.PurePath(*p.parts[:i])
return None
Upvotes: 0
Reputation: 11338
You use can use dirname
on abspath
of __file__
to get the full path of the x.xml:
os.path.dirname(os.path.abspath(__file__))
>>> import pathlib
>>> p = pathlib.PurePath('a/b/c/d/e/f/x.xml')
>>> p.parts
('a', 'b', 'c', 'd', 'f', 'x.xml')
Then you can extract any part of your path. If you want to get the d
folder:
import itertools
res = '/'.join(itertools.takewhile(lambda x: x != 'd', p.parts))
Upvotes: 2
Reputation: 100
Use regexp and cut:
import re
import os
mydir_regexp = re.compile('dirname')
abs_path = os.path.abspath(__file__)
s = re.search(mydir_regexp, abs_path)
my_match = abs_path[:abs_path.index(s.group())+len(s.group())]
Upvotes: 0