从路径中提取文件名,无论 os/path 格式如何

2024-12-06 08:40:00
admin
原创
104
摘要:问题描述:无论操作系统或路径格式如何,我可以使用哪个 Python 库从路径中提取文件名?例如,我希望所有这些路径都返回我c:a/b/c/ a/b/c ac ac\nac a/b/../../a/b/c/ a/b/../../a/b/c 解决方案 1:有一个函数可以返回你想要的结果import os p...

问题描述:

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

例如,我希望所有这些路径都返回我c

a/b/c/
a/b/c
ac
ac\nac
a/b/../../a/b/c/
a/b/../../a/b/c

解决方案 1:

有一个函数可以返回你想要的结果

import os
print(os.path.basename(your_path))

警告:在os.path.basename()POSIX 系统上使用时从 Windows 风格的路径获取基本名称(例如"C:\my\file.txt"),将返回整个路径。

下面的示例来自在 Linux 主机上运行的交互式 Python Shell:

Python 3.8.2 (default, Mar 13 2020, 10:14:16)
[GCC 9.3.0] on Linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> filepath = "C:\\my\\path\\to\\file.txt" # A Windows style file path.
>>> os.path.basename(filepath)
'C:\\my\\path\\to\\file.txt'

解决方案 2:

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

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

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

(1) 有一个警告:Linux 文件名可能包含反斜杠。因此,在 Linux 上,r'a/bc'始终指文件夹bc中的文件a,而在 Windows 上,它始终指文件夹子文件夹c中的文件。因此,当路径中同时使用正斜杠和反斜杠时,您需要了解相关平台才能正确解释它。实际上,通常可以安全地假设它是 Windows 路径,因为反斜杠很少用于 Linux 文件名中,但在编码时请记住这一点,以免造成意外的安全漏洞。b`a`

解决方案 3:

os.path.split
是你正在寻找的函数

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

>>> print(tail)
a.dat
>>> print(head)
/tmp/d

解决方案 4:

在 Python 3.4 或更高版本中,使用pathlib.Path

>>> from pathlib import Path    
>>> Path("/tmp/d/a.dat").name
'a.dat'

.name属性将给出路径中最终子元素的全名,无论它是文件还是文件夹。

解决方案 5:

import os
head, tail = os.path.split('path/to/file.exe')

tail 就是你想要的文件名。

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

解决方案 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

解决方案 7:

我个人最喜欢的是:

filename = fullname.split(os.sep)[-1]

解决方案 8:

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

import glob

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

解决方案 9:

在您的示例中,您还需要从右侧删除斜线以返回c

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

第二级:

>>> os.path.filename(os.path.dirname(path))
'b'

更新:我认为lazyr已经给出了正确的答案。我的代码无法在 unix 系统上使用类似 windows 的路径,反之亦然。

解决方案 10:

fname = str("C:Windowspaint.exe").split('\\')[-1:][0]

这将返回:paint.exe

根据您的路径或操作系统更改 split 函数的 sep 值。

解决方案 11:

带扩展名的文件名

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

print(type(basename))
# <class 'str'>

文件名不带扩展名

basename_without_ext = os.path.splitext(os.path.basename(filepath))[0]
print(basename_without_ext)
# filename

解决方案 12:

这是工作!

os.path.basename(name)

但是你无法通过 Windows 文件路径在 Linux 中获取文件名。Windows 也一样。os.path 在不同的操作系统上加载不同的模块:

  • Linux - posixpath

  • Windows——npath

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

解决方案 13:

这对于 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]

结果:

['c', 'c', 'c', 'c', 'c', 'c', 'c']

解决方案 14:

如果您的文件路径不是以“/”结尾,且目录以“/”分隔,则使用以下代码。众所周知,路径通常不以“/”结尾。

import os
path_str = "/var/www/index.html"
print(os.path.basename(path_str))

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

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

但是当你的路径被“\”分隔时(通常在 Windows 路径中可以找到),你可以使用以下代码

import os
path_str = "c:\\varwwwindex.html"
print(os.path.basename(path_str))

import os
path_str = "c:\\homesome_strlast_str\\\"
split_path = path_str.rsplit("\\\",1)
print(os.path.basename(split_path[0]))

您可以通过检查操作系统类型并返回结果将两者合并为一个函数。

解决方案 15:

这是一个仅正则表达式的解决方案,它似乎适用于任何操作系统上的任何操作系统路径。

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

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

print([extract_basename(path) for path in extra_paths])
# ['C:', 'alone', 'space in filename', 'multi
line']

更新:

如果您只想要一个潜在文件名(如果存在)(即/a/b/是目录并且也是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:windowssystem32 # matches potential filename 'system32', except
                    # that is obviously a dir. os.path.is_dir()
                    # should be used to tell us for sure

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

解决方案 16:

import os

path = r"C:py_auto_script    esting.xlsx"
os.path.basename(path)
=> 'testing.xlsx'

os.path.dirname(os.path.realpath(path))
=>'C:\\py_auto_script'

解决方案 17:

也许只是我的一体化解决方案,没有一些重要的新内容(考虑用于创建临时文件的临时文件:D)

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

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

无需导入任何模块。

解决方案 18:

如果目录中有多个文件,并且想要将这些文件名存储到列表中。请使用以下代码。

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)

解决方案 19:

我从未见过双反斜杠路径,它们存在吗?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/c']
for path in paths:
    os.path.basename(os.path.normpath(path))

解决方案 20:

Windows 分隔符可以位于 Unix 文件名或 Windows 路径中。Unix 分隔符只能存在于 Unix 路径中。Unix 分隔符的存在表示非 Windows 路径。

下面将按操作系统特定的分隔符剥离(剪切尾随分隔符),然后拆分并返回最右边的值。这很丑陋,但基于上述假设很简单。如果假设不正确,请更新,我会更新此回复以匹配更准确的条件。

a.rstrip("\\\\\" if a.count("/") == 0 else '/').split("\\\\\" if a.count("/") == 0 else '/')[-1]

示例代码:

b = ['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']

for a in b:

    print (a, a.rstrip("\\\" if a.count("/") == 0 else '/').split("\\\" if a.count("/") == 0 else '/')[-1])

解决方案 21:

为了完整起见,这里是pathlib针对 Python 3.2+ 的解决方案:

>>> from pathlib import PureWindowsPath

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

>>> [PureWindowsPath(path).name for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']

这在 Windows 和 Linux 上都有效。

解决方案 22:

在 Python 2 和 3 中,使用模块pathlib2:

import posixpath  # to generate unix paths
from pathlib2 import PurePath, PureWindowsPath, PurePosixPath

def path2unix(path, nojoin=True, fromwinpath=False):
    """From a path given in any format, converts to posix path format
    fromwinpath=True forces the input path to be recognized as a Windows path (useful on Unix machines to unit test Windows paths)"""
    if not path:
        return path
    if fromwinpath:
        pathparts = list(PureWindowsPath(path).parts)
    else:
        pathparts = list(PurePath(path).parts)
    if nojoin:
        return pathparts
    else:
        return posixpath.join(*pathparts)

用法:

In [9]: path2unix('lala/lolo/haha.dat')
Out[9]: ['lala', 'lolo', 'haha.dat']

In [10]: path2unix(r'C:lala/lolo/haha.dat')
Out[10]: ['C:\\', 'lala', 'lolo', 'haha.dat']

In [11]: path2unix(r'C:lala/lolo/haha.dat') # works even with malformatted cases mixing both Windows and Linux path separators
Out[11]: ['C:\\', 'lala', 'lolo', 'haha.dat']

使用您的测试用例:

In [12]: testcase = 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']

In [14]: for t in testcase:
    ...:     print(path2unix(t)[-1])
    ...:
    ...:
c
c
c
c
c
c
c

这里的想法是将所有路径转换为 ​​的统一内部表示pathlib2,根据平台使用不同的解码器。幸运的是,pathlib2包含一个通用解码器,称为PurePath,它应该适用于任何路径。如果这不起作用,您可以使用 强制识别 windows 路径fromwinpath=True。这会将输入字符串拆分成几部分,最后一部分是您要查找的叶子,因此path2unix(t)[-1]

如果参数为nojoin=False,路径将被重新连接,以便输出只是将输入字符串转换为 Unix 格式,这对于跨平台比较子路径很有用。

解决方案 23:

我在 Windows 和 Ubuntu(WSL)上使用此方法,它仅使用“import os”即可按(我)预期的方式工作:所以基本上,replace() 会根据您当前的操作系统平台放置正确的路径分隔符。

如果路径以斜杠“/”结尾,那么它不是文件而是目录,因此它返回一个空字符串。

import os

my_fullpath = r"D:MY_FOLDERTEST‚01108‚01108_073751.DNG"
os.path.basename(my_fullpath.replace('\\',os.sep))

my_fullpath = r"/MY_FOLDER/TEST/20201108/20201108_073751.DNG"
os.path.basename(my_fullpath.replace('\\',os.sep))

my_fullpath = r"/MY_FOLDER/TEST/20201108/"
os.path.basename(my_fullpath.replace('\\',os.sep))

my_fullpath = r"/MY_FOLDER/TEST/20201108"
os.path.basename(my_fullpath.replace('\\',os.sep))

在 Windows(左)和 Ubuntu(通过 WSL,右)上:
在此处输入图片描述

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1109  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   73  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   63  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   71  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   66  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用