snippetpythonCriticalCanonical
Extract file name from path, no matter what the os/path format
Viewed 0 times
matterfromextractnamethefilepathformatwhat
Problem
Which Python library can I use to extract filenames from paths, no matter what the operating system or path format could be?
For example, I'd like all of these paths to return me
For example, I'd like all of these paths to return me
c:a/b/c/
a/b/c
\a\b\c
\a\b\c\
a\b\c
a/b/../../a/b/c/
a/b/../../a/b/cSolution
Using
Windows paths can use either backslash or forward slash as path separator. Therefore, the
Of course, if the file ends with a slash, the basename will be empty, so make your own function to deal with it:
Verification:
(1) There's one caveat: Linux filenames may contain backslashes. So on linux,
os.path.split or os.path.basename as others suggest won't work in all cases: if you're running the script on Linux and attempt to process a classic windows-style path, it will fail.Windows paths can use either backslash or forward slash as path separator. Therefore, the
ntpath module (which is equivalent to os.path when running on windows) will work for all(1) paths on all platforms.import ntpath
ntpath.basename("a/b/c")Of course, if the file ends with a slash, the basename will be empty, so make your own function to deal with it:
def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)Verification:
>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
... 'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c'](1) There's one caveat: Linux filenames may contain backslashes. So on linux,
r'a/b\c' always refers to the file b\c in the a folder, while on Windows, it always refers to the c file in the b subfolder of the a folder. So when both forward and backward slashes are used in a path, you need to know the associated platform to be able to interpret it correctly. In practice it's usually safe to assume it's a windows path since backslashes are seldom used in Linux filenames, but keep this in mind when you code so you don't create accidental security holes.Code Snippets
import ntpath
ntpath.basename("a/b/c")def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
... 'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']Context
Stack Overflow Q#8384737, score: 1070
Revisions (0)
No revisions yet.