1

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")
Amarsh
  • 11,214
  • 18
  • 53
  • 78

5 Answers5

2

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))
Chen A.
  • 10,140
  • 3
  • 42
  • 61
2

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
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
0

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())]
0

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
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

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.

Amarsh
  • 11,214
  • 18
  • 53
  • 78