Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing the first folder in a path

Tags:

python

path

I have a path which looks like

/First/Second/Third/Fourth/Fifth 

and I would like to remove the First from it, thus obtaining

Second/Third/Fourth/Fifth 

The only idea I could come up with is to use recursively os.path.split but this does not seem optimal. Is there a better solution?

like image 481
meto Avatar asked Nov 03 '14 22:11

meto


People also ask

How do you split a path in Python?

path. split() method in Python is used to Split the path name into a pair head and tail. Here, tail is the last path name component and head is everything leading up to that.

How do I change a path in Python?

replace() method in Python is used to rename the file or directory. If destination is a directory, OSError will be raised. If the destination exists and is a file, it will be replaced without error if the action performing user has permission.

What is OS Pathsep?

The os. pathsep indicates the character used by the operating system to separate search path components. The value for os. pathsep is : for POSIX and ; for Windows.


2 Answers

There really is nothing in the os.path module to do this. Every so often, someone suggests creating a splitall function that returns a list (or iterator) of all of the components, but it never gained enough traction.

Partly this is because every time anyone ever suggested adding new functionality to os.path, it re-ignited the long-standing dissatisfaction with the general design of the library, leading to someone proposing a new, more OO-like, API for paths to deprecated the os, clunky API. In 3.4, that finally happened, with pathlib. And it's already got functionality that wasn't in os.path. So:

>>> import pathlib >>> p = pathlib.Path('/First/Second/Third/Fourth/Fifth') >>> p.parts[2:] ('Third', 'Fourth', 'Fifth') >>> pathlib.Path(*p.parts[2:]) PosixPath('Second/Third/Fourth/Fifth') 

Or… are you sure you really want to remove the first component, rather than do this?

>>> p.relative_to(*p.parts[:2]) PosixPath('Second/Third/Fourth/Fifth') 

If you need to do this in 2.6-2.7 or 3.2-3.3, there's a backport of pathlib.

Of course, you can use string manipulation, as long as you're careful to normalize the path and use os.path.sep, and to make sure you handle the fiddly details with non-absolute paths or with systems with drive letters, and…

Or you can just wrap up your recursive os.path.split. What exactly is "non-optimal" about it, once you wrap it up? It may be a bit slower, but we're talking nanoseconds here, many orders of magnitude faster than even calling stat on a file. It will have recursion-depth problems if you have a filesystem that's 1000 directories deep, but have you ever seen one? (If so, you can always turn it into a loop…) It takes a few minutes to wrap it up and write good unit tests, but that's something you just do once and never worry about again. So, honestly, if you don't want to use pathlib, that's what I'd do.

like image 115
abarnert Avatar answered Sep 21 '22 13:09

abarnert


A bit like another answer, taking advantage of os.path :

os.path.join(*(x.split(os.path.sep)[2:])) 

... assuming your string starts with a separator.

like image 20
amyrit Avatar answered Sep 21 '22 13:09

amyrit