'python Pathlib, how do I remove leading directories to get relative paths?

Let's say I have this directory structure.

├── root1
│   └── root2
│       ├── bar
│       │   └── file1
│       ├── foo
│       │   ├── file2
│       │   └── file3
│       └── zoom
│           └── z1
│               └── file41

I want to isolate path components relative to root1/root2, i.e. strip out the leading root part, giving relative directories:

  bar/file1
  foo/file3
  zoom/z1/file41

The root depth can be arbitrary and the files, the node of this tree, can also reside at different levels.

This code does it, but I am looking for Pathlib's pythonic way to do it.

from pathlib import Path
import os

#these would come from os.walk or some glob...
file1 = Path("root1/root2/bar/file1")
file2 = Path("root1/root2/foo/file3")
file41 = Path("root1/root2/zoom/z1/file41")

root = Path("root1/root2")

#take out the root prefix by string replacement.
for file_ in [file1, file2, file41]:

    #is there a PathLib way to do this?🤔
    file_relative = Path(str(file_).replace(str(root),"").lstrip(os.path.sep))
    print("  %s" % (file_relative))


Solution 1:[1]

TLDR: use Path.relative_to:

Path("a/b/c").relative_to("a/b")  # returns PosixPath('c')

Full example:

from pathlib import Path
import os

# these would come from os.walk or some glob...
file1 = Path("root1/root2/bar/file1")
file2 = Path("root1/root2/foo/file3")
file41 = Path("root1/root2/zoom/z1/file41")

root = Path("root1/root2")

# take out the root prefix by string replacement.
for file_ in [file1, file2, file41]:

    # is there a PathLib way to do this??
    file_relative = file_.relative_to(root)
    print("  %s" % (file_relative))

Prints

  bar\file1
  foo\file3
  zoom\z1\file41

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1