335

In , suppose I have a path like this:

/folderA/folderB/folderC/folderD/

How can I get just the folderD part?

M.Innat
  • 13,008
  • 6
  • 38
  • 74
pepero
  • 6,531
  • 7
  • 39
  • 70

10 Answers10

535

Use os.path.normpath, then os.path.basename:

>>> os.path.basename(os.path.normpath('/folderA/folderB/folderC/folderD/'))
'folderD'

The first strips off any trailing slashes, the second gives you the last part of the path. Using only basename gives everything after the last slash, which in this case is ''.

Fred Foo
  • 342,876
  • 71
  • 713
  • 819
  • 2
    I initially thought `rstrip('/')` would be simpler but then quickly realised I'd have to use `rstrip(os.path.sep)`, so obviously the use of `normpath` is justified. – Erik Kaplun Jun 29 '14 at 13:44
  • This doesn't seem to work on Windows long paths, e.g., `'\\\\?\\D:\\A\\B\\C\\'` and `'\\\\?\\UNC\\svr\\B\\C\\'` (returns an empty string) [This](https://stackoverflow.com/a/8384788/5659969) solution works for all cases. – omasoud Feb 07 '20 at 17:54
  • @jinnlao's [answer](https://stackoverflow.com/a/54868730/9835872) is much much better nowadays. – ruohola Jun 30 '21 at 13:18
84

With python 3 you can use the pathlib module (pathlib.PurePath for example):

>>> import pathlib

>>> path = pathlib.PurePath('/folderA/folderB/folderC/folderD/')
>>> path.name
'folderD'

If you want the last folder name where a file is located:

>>> path = pathlib.PurePath('/folderA/folderB/folderC/folderD/file.py')
>>> path.parent.name
'folderD'
jinnlao
  • 971
  • 7
  • 6
  • 4
    well, just to point it out `PurePath` vs `Path`, the first provides "purely computational operations" (no I/O), while the other ("concrete path") inherits from the first but also provides I/O operations. – Paolo Dec 25 '20 at 17:14
31

You could do

>>> import os
>>> os.path.basename('/folderA/folderB/folderC/folderD')

UPDATE1: This approach works in case you give it /folderA/folderB/folderC/folderD/xx.py. This gives xx.py as the basename. Which is not what you want I guess. So you could do this -

>>> import os
>>> path = "/folderA/folderB/folderC/folderD"
>>> if os.path.isdir(path):
        dirname = os.path.basename(path)

UPDATE2: As lars pointed out, making changes so as to accomodate trailing '/'.

>>> from os.path import normpath, basename
>>> basename(normpath('/folderA/folderB/folderC/folderD/'))
'folderD'
Srikar Appalaraju
  • 69,116
  • 53
  • 210
  • 260
  • In Python-think, os.path.basename(".../") correctly yields ''. Yes, I, too, find that sub-optimal. The ...basename(...normpath... solution below is canonical, though. – Cameron Laird Oct 13 '10 at 15:11
  • @lars yeah! just saw that in that case normalize the path first before feeding it to basename. os.path.basename(os.path.normpath('/folderA/folderB/folderC/folderD/')) – Srikar Appalaraju Oct 13 '10 at 15:12
  • UPDATE2 is the best approach I have found so far. – akki May 28 '15 at 09:22
22

Here is my approach:

>>> import os
>>> print os.path.basename(
        os.path.dirname('/folderA/folderB/folderC/folderD/test.py'))
folderD
>>> print os.path.basename(
        os.path.dirname('/folderA/folderB/folderC/folderD/'))
folderD
>>> print os.path.basename(
        os.path.dirname('/folderA/folderB/folderC/folderD'))
folderC
Mike Mitterer
  • 6,002
  • 3
  • 37
  • 54
  • 1
    What does your approach solve different/better than the aforementioned? – user1767754 Jan 16 '18 at 00:17
  • @user1767754: though terse, this does illustrate a solution that works with our without a file name, while also showing the pitfall if a final directory does not have a trailing `/` (and without needing purepath) – Bryan P Mar 19 '21 at 18:19
10

I was searching for a solution to get the last foldername where the file is located, I just used split two times, to get the right part. It's not the question but google transfered me here.

pathname = "/folderA/folderB/folderC/folderD/filename.py"
head, tail = os.path.split(os.path.split(pathname)[0])
print(head + "   "  + tail)
Shaido
  • 25,575
  • 21
  • 68
  • 72
user1767754
  • 21,126
  • 14
  • 125
  • 152
  • 3
    You can also use `os.path.basename(os.path.dirname(pathname))` which would give `folderD` in your example. See answer from @Mike Miterer – Bryan P Mar 19 '21 at 18:17
8

I like the parts method of Path for this:

grandparent_directory, parent_directory, filename = Path(export_filename).parts[-3:]
log.info(f'{t: <30}: {num_rows: >7} Rows exported to {grandparent_directory}/{parent_directory}/{filename}')
Andrew Magerman
  • 1,374
  • 13
  • 23
4

If you use the native python package pathlib it's really simple.

>>> from pathlib import Path
>>> your_path = Path("/folderA/folderB/folderC/folderD/")
>>> your_path.stem
'folderD'

Suppose you have the path to a file in folderD.

>>> from pathlib import Path
>>> your_path = Path("/folderA/folderB/folderC/folderD/file.txt")
>>> your_path.name
'file.txt'
>>> your_path.parent
'folderD'
CB Madsen
  • 454
  • 6
  • 8
  • 1
    In your 2nd example `stem` will only return `file` not `file.txt`. If you want `file.txt` you need `your_path.name`. [Pathlib Docs](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.stem) – Matthew Barlowe Mar 14 '22 at 15:28
0

During my current projects, I'm often passing rear parts of a path to a function and therefore use the Path module. To get the n-th part in reverse order, I'm using:

from typing import Union
from pathlib import Path

def get_single_subpath_part(base_dir: Union[Path, str], n:int) -> str:
    if n ==0:
        return Path(base_dir).name
    for _ in range(n):
        base_dir = Path(base_dir).parent
    return getattr(base_dir, "name")

path= "/folderA/folderB/folderC/folderD/"

# for getting the last part:
print(get_single_subpath_part(path, 0))
# yields "folderD"

# for the second last
print(get_single_subpath_part(path, 1))
#yields "folderC"

Furthermore, to pass the n-th part in reverse order of a path containing the remaining path, I use:

from typing import Union
from pathlib import Path

def get_n_last_subparts_path(base_dir: Union[Path, str], n:int) -> Path:
    return Path(*Path(base_dir).parts[-n-1:])

path= "/folderA/folderB/folderC/folderD/"

# for getting the last part:
print(get_n_last_subparts_path(path, 0))
# yields a `Path` object of "folderD"

# for second last and last part together 
print(get_n_last_subparts_path(path, 1))
# yields a `Path` object of "folderc/folderD"

Note that this function returns a Pathobject which can easily be converted to a string (e.g. str(path))

dheinz
  • 682
  • 8
  • 13
-2
path = "/folderA/folderB/folderC/folderD/"
last = path.split('/').pop()
GSto
  • 40,278
  • 37
  • 127
  • 179
-5
str = "/folderA/folderB/folderC/folderD/"
print str.split("/")[-2]
Andrew Sledge
  • 9,907
  • 2
  • 27
  • 29