无论os/path格式是什么,都可以从路径中提取文件名

BuZ*_*uZz 690 python

无论操作系统或路径格式是什么,我可以使用哪个Python库从路径中提取文件名?

例如,我希望所有这些路径都能归还给我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/c
Run Code Online (Sandbox Code Playgroud)

str*_*nac 1107

实际上,有一个功能可以准确地返回您想要的功能

import os
print(os.path.basename(your_path))
Run Code Online (Sandbox Code Playgroud)

  • 如果要以独立于操作系统的方式处理路径,那么对于os.path.basename(u"C:\\ temp \\ bla.txt"),您希望得到'bla.txt'.问题不是获取有效的文件名,而是提取路径的名称. (21认同)
  • 在Linux上尝试,使用Linux路径! (8认同)
  • @ johnc.j.关键是,当你在Linux上尝试这个时,你会得到`'C:\\ temp \\ bla.txt'. (7认同)
  • `os.path.basename(your_path)` 这有效!我想要脚本路径:`os.path.dirname(os.path.realpath(__file__))` 和脚本名称:`os.path.basename(os.path.realpath(__file__))`。谢谢! (5认同)
  • @stranac你是对的,Linux实现非常以自我为中心,不将路径中的反斜杠视为正确的路径分隔符。好的一面是,Windows 风格的路径_确实_可以在 Linux 上工作,但你必须仅使用 ___ 正斜杠___(因此你可以执行 `filepath.replace('\\', '/')` 来获得一些平台独立性) (4认同)
  • 在我的Google搜索中找到路径的文件名,这个答案是最有帮助的.无论如何,我的用例仅适用于Windows. (3认同)
  • 在Windows 10上尝试过,工作正常! (2认同)

Lau*_*low 695

使用os.path.splitos.path.basename作为其他人建议不会在所有情况下都有效:如果您在Linux上运行脚本并尝试处理经典的Windows样式路径,它将失败.

Windows路径可以使用反斜杠或正斜杠作为路径分隔符.因此,ntpath模块(在Windows上运行时相当于os.path)将适用于所有平台上的所有(1)路径.

import ntpath
ntpath.basename("a/b/c")
Run Code Online (Sandbox Code Playgroud)

当然,如果文件以斜杠结尾,则basename将为空,因此请创建自己的函数来处理它:

def path_leaf(path):
    head, tail = ntpath.split(path)
    return tail or ntpath.basename(head)
Run Code Online (Sandbox Code Playgroud)

验证:

>>> 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']
Run Code Online (Sandbox Code Playgroud)


(1)有一点需要注意:Linux文件名可能包含反斜杠.所以在linux上,r'a/b\c'总是指文件夹b\c中的a文件,而在Windows上,它总是引用c文件b夹子文件夹中的a文件.因此,当在路径中使用向前和向后斜杠时,您需要知道相关平台才能正确解释它.在实践中,通常可以安全地假设它是一个Windows路径,因为反斜杠在Linux文件名中很少使用,但在编码时请记住这一点,这样就不会产生意外的安全漏洞.

  • 在Windows上,`os.path`只是在内部加载`ntpath`模块.使用这个模块,即使在Linux机器上也可以处理`'\\'`路径分隔符.对于Linux,`posixpath`模块(相应的`os.path`)将简化路径操作,只允许posix样式的''/'分隔符. (22认同)
  • 对于这个问题的未来访问者的价值,我遇到了劳里茨警告的情况,他的解决方案是唯一有效的解决方案。没有与 os 纠缠只能输出文件名。所以恕我直言, ntpath 是要走的路。 (4认同)
  • @ johnc.j.只有当您需要在Linux机器上解析Windows样式路径(例如,`r'C:\ path\to\file.txt'`)时,才需要使用ntpath模块.否则,您可以使用os.path中的函数.这是因为Linux系统通常允许在文件名中使用反斜杠字符(如答案中所述). (3认同)
  • @moooeeeeep 所以我们可以使用 Stranac 的答案,它可靠吗?(**"像其他人建议的那样使用 os.path.split 或 os.path.basename 在所有情况下都不起作用:如果您在 Linux 上运行脚本并尝试处理经典的 Windows 样式路径,它将失败“**——引自劳里茨的帖子——我不明白,这个警告是否与斯特拉纳克的回答有关,或者不)。 (2认同)
  • 你的解决方案不是等同于 `os.path.basename(os.path.normpath(path))` 吗? (2认同)

Jak*_*yer 199

os.path.split 是您正在寻找的功能

head, tail = os.path.split("/tmp/d/a.dat")

>>> print(tail)
a.dat
>>> print(head)
/tmp/d
Run Code Online (Sandbox Code Playgroud)

  • 只是为了让其他用户小心,如果路径以"/"或"\"结尾,则返回"" (39认同)
  • @ amitnair92-执行以下操作:r“ C:\ Users \ Dell \ Desktop \ ProjectShadow \ button \ button.py”或执行以下操作:“ C:\\ Users \\ Dell \\ Desktop \\ ProjectShadow \\ button \\ button .py“-” \ b“是一个特殊字符(我认为是系统的“钟”),类似于\ r或\ n表示换行符/回车符的方式。用r“ C:\ ...”前缀字符串意味着使用给定的原始输入 (4认同)

Kis*_*n B 58

在python 3中

>>> from pathlib import Path    
>>> Path("/tmp/d/a.dat").name
'a.dat'
Run Code Online (Sandbox Code Playgroud)

  • 还可以使用 Path("some/path/to/file.dat").stem 获取不带文件扩展名的文件名 (41认同)
  • ...并且 `pathlib.Path('some/path/to/file.dat').suffix` 产生扩展名。 (4认同)

num*_*er5 37

import os
head, tail = os.path.split(p)
print tail
Run Code Online (Sandbox Code Playgroud)

假设p是输入字符串,tail就是你想要的.

有关详细信息,请参阅python os模块文档

  • 只是为了让其他用户小心,如果路径以"/"或"\"结尾,则返回"" (11认同)

vin*_*inu 19

如果你想自动获取文件名,你可以这样做

import glob

for f in glob.glob('/your/path/*'):
    print(os.path.split(f)[-1])
Run Code Online (Sandbox Code Playgroud)


jon*_*yrn 14

我个人最喜欢的是:

filename = fullname.split(os.sep)[-1]
Run Code Online (Sandbox Code Playgroud)


Ski*_*Ski 12

在您的示例中,您还需要从右侧剥离斜线以返回c:

>>> import os
>>> path = 'a/b/c/'
>>> path = path.rstrip(os.sep) # strip the slash from the right side
>>> os.path.basename(path)
'c'
Run Code Online (Sandbox Code Playgroud)

第二级:

>>> os.path.filename(os.path.dirname(path))
'b'
Run Code Online (Sandbox Code Playgroud)

更新:我认为lazyr已经提供了正确的答案.我的代码不适用于unix系统上的类似Windows的路径,也不适用于Windows系统上的类似unix的路径.


Ali*_*hsh 12

带扩展名的文件名

filepath = './dir/subdir/filename.ext'
basename = os.path.basename(filepath)
print(basename)
# filename.ext

print(type(basename))
# <class 'str'>
Run Code Online (Sandbox Code Playgroud)

不带扩展名的文件名

basename_without_ext = os.path.splitext(os.path.basename(filepath))[0]
print(basename_without_ext)
# filename
Run Code Online (Sandbox Code Playgroud)


小智 11

它\xe2\x80\x99 可以工作!

\n
os.path.basename(name)\n
Run Code Online (Sandbox Code Playgroud)\n

但是你不能通过 Windows 文件路径在 Linux 中\xe2\x80\x99 获取文件名。Windows 也是如此。\nos.path 在不同的操作系统上加载不同的模块:

\n
    \n
  • Linux-posixpath
  • \n
  • Windows-npath
  • \n
\n

所以你可以使用 os.path 始终获得正确的结果

\n


Esl*_*uda 9

fname = str("C:\Windows\paint.exe").split('\\')[-1:][0]
Run Code Online (Sandbox Code Playgroud)

这将返回:paint.exe

更改有关路径或操作系统的拆分功能的sep值.

  • 这是我喜欢的答案,但为什么不直接执行以下操作呢?```fname = str(path).split('/')[-1]``` (2认同)

Ake*_*ndo 7

也许只是我的所有解决方案,而没有一些重要的新解决方案(关于用于创建临时文件的临时文件:D)

import tempfile
abc = tempfile.NamedTemporaryFile(dir='/tmp/')
abc.name
abc.name.replace("/", " ").split()[-1] 
Run Code Online (Sandbox Code Playgroud)

获取 的值abc.name将是这样的字符串:'/tmp/tmpks5oksk7' 所以我可以用/空格替换.replace("/", " "),然后调用split(). 这将返回一个列表,我得到列表的最后一个元素[-1]

无需导入任何模块。

  • 如果文件名或目录包含空格怎么办? (3认同)
  • 直接 split("/")[-1] 怎么样? (2认同)

小智 7

这适用于linux和windows以及标准库

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']

def path_leaf(path):
    return path.strip('/').strip('\\').split('/')[-1].split('\\')[-1]

[path_leaf(path) for path in paths]
Run Code Online (Sandbox Code Playgroud)

结果:

['c', 'c', 'c', 'c', 'c', 'c', 'c']
Run Code Online (Sandbox Code Playgroud)


San*_*nda 7

如果您的文件路径不以“ /”结尾并且目录以“ /”分隔,则使用以下代码。我们知道,路径通常不以“ /”结尾。

import os
path_str = "/var/www/index.html"
print(os.path.basename(path_str))
Run Code Online (Sandbox Code Playgroud)

但是在某些情况下,例如URL以“ /”结尾,然后使用以下代码

import os
path_str = "/home/some_str/last_str/"
split_path = path_str.rsplit("/",1)
print(os.path.basename(split_path[0]))
Run Code Online (Sandbox Code Playgroud)

但是,当您的路径通常在Windows路径中以“ \”分隔时,则可以使用以下代码

import os
path_str = "c:\\var\www\index.html"
print(os.path.basename(path_str))

import os
path_str = "c:\\home\some_str\last_str\\"
split_path = path_str.rsplit("\\",1)
print(os.path.basename(split_path[0]))
Run Code Online (Sandbox Code Playgroud)

您可以通过检查OS类型将两者组合为一个功能并返回结果。


Gau*_*rav 7

如果您在一个目录中有许多文件并且想要将这些文件名存储到一个列表中。使用下面的代码。

import os as os
import glob as glob
path = 'mypath'
file_list= []
for file in glob.glob(path):
    data_file_list = os.path.basename(file)
    file_list.append(data_file_list)
Run Code Online (Sandbox Code Playgroud)


Eri*_*nil 6

这是仅用于正则表达式的解决方案,它似乎可与任何OS上的任何OS路径一起使用。

不需要其他模块,也不需要预处理:

import re

def extract_basename(path):
  """Extracts basename of a given path. Should Work with any OS Path on any OS"""
  basename = re.search(r'[^\\/]+(?=[\\/]?$)', path)
  if basename:
    return basename.group(0)


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']

print([extract_basename(path) for path in paths])
# ['c', 'c', 'c', 'c', 'c', 'c', 'c']


extra_paths = ['C:\\', 'alone', '/a/space in filename', 'C:\\multi\nline']

print([extract_basename(path) for path in extra_paths])
# ['C:', 'alone', 'space in filename', 'multi\nline']
Run Code Online (Sandbox Code Playgroud)

更新:

如果只需要一个潜在的文件名(如果存在)(即/a/b/dir,也是如此c:\windows\),则将正则表达式更改为:r'[^\\/]+(?![\\/])$'。对于“正则表达式挑战”,这会将某种斜杠的正向正向查找更改为负向正向查找,从而导致以所述斜杠结尾的路径名不返回任何内容,而不返回路径名中的最后一个子目录。当然,不能保证潜在的文件名实际上是指文件,并且为此os.path.is_dir()os.path.is_file()将需要使用。

这将匹配如下:

/a/b/c/             # nothing, pathname ends with the dir 'c'
c:\windows\         # nothing, pathname ends with the dir 'windows'
c:hello.txt         # matches potential filename 'hello.txt'
~it_s_me/.bashrc    # matches potential filename '.bashrc'
c:\windows\system32 # matches potential filename 'system32', except
                    # that is obviously a dir. os.path.is_dir()
                    # should be used to tell us for sure
Run Code Online (Sandbox Code Playgroud)

可以在这里测试正则表达式。


Sau*_*tel 6

import os
file_location = '/srv/volume1/data/eds/eds_report.csv'
file_name = os.path.basename(file_location )  #eds_report.csv
location = os.path.dirname(file_location )    #/srv/volume1/data/eds
Run Code Online (Sandbox Code Playgroud)


Pyt*_*Nic 5

我从未见过双背路径,它们是否存在?python模块的内置功能os失败了.所有其他人的工作,以及您给出的警告os.path.normpath():

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', 'a/./b/c', 'a\b/c']
for path in paths:
    os.path.basename(os.path.normpath(path))
Run Code Online (Sandbox Code Playgroud)

  • 这些不是双反斜杠。它们是单反斜杠,需要转义。 (2认同)