replace part of path - python

>>> import os.path
>>> old_path='/abc/dfg/ghi/f.txt'

First grab the relative path from the starting directory of your choice using os.path.relpath

>>> rel = os.path.relpath(old_path, '/abc/dfg/')
>>> rel
'ghi\\f.txt'

Then add the new first part of the path to this relative path using os.path.join

>>> new_path = os.path.join('jkl\mno', rel)
>>> new_path
'jkl\\mno\\ghi\\f.txt'

If you're using Python 3.4+, or willing to install the backport, consider using pathlib instead of os.path:

path = pathlib.Path(old_path)
index = path.parts.index('ghi')
new_path = pathlib.Path('/jkl/mno').joinpath(*path.parts[index:])

If you just want to stick with the 2.7 or 3.3 stdlib, there's no direct way to do this, but you can get the equivalent of parts by looping over os.path.split. For example, keeping each path component until you find the first ghi, and then tacking on the new prefix, will replace everything before the last ghi (if you want to replace everything before the first ghi, it's not hard to change things):

path = old_path
new_path = ''
while True:
    path, base = os.path.split(path)
    new_path = os.path.join(base, new_path)
    if base == 'ghi':
        break
new_path = os.path.join('/jkl/mno', new_path)

This is a bit clumsy, so you might want to consider writing a simple function that gives you a list or tuple of the path components, so you can just use find, then join it all back together, as with the pathlib version.


You can use the index of ghi:

old_path.replace(old_path[:old_path.index("ghi")],"/jkl/mno/")
In [4]: old_path.replace(old_path[:old_path.index("ghi")],"/jkl/mno/" )
Out[4]: '/jkl/mno/ghi/f.txt'