如何从Python中的路径中获取没有扩展名的文件名?

如何从Python中的路径中获取没有扩展名的文件名?

"/path/to/some/file.txt"  →  "file"
1851663 次浏览

获取不带扩展名的文件名:

import osprint(os.path.splitext("/path/to/some/file.txt")[0])

打印:

/path/to/some/file

#0的文档.

重要提示:如果文件名有多个点,则仅删除最后一个点之后的扩展名。例如:

import osprint(os.path.splitext("/path/to/some/file.txt.zip.asc")[0])

打印:

/path/to/some/file.txt.zip

如果您需要处理这种情况,请参阅下面的其他答案。

但即使我导入os,我也不能调用它path.basename.可以像basename一样直接调用它吗?

import os,然后使用os.path.basename

importingos并不意味着你可以使用os.foo而不引用os

你可以自己做:

>>> import os>>> base=os.path.basename('/root/dir/sub/file.ext')>>> base'file.ext'>>> os.path.splitext(base)('file', '.ext')>>> os.path.splitext(base)[0]'file'

重要提示:如果文件名中有多个.,则仅删除最后一个。例如:

/root/dir/sub/file.ext.zip -> file.ext
/root/dir/sub/file.ext.tar.gz -> file.ext.tar

请参阅下面的其他答案来解决这个问题。

>>> print(os.path.splitext(os.path.basename("/path/to/file/hemanth.txt"))[0])hemanth

在Windows系统上,我也使用了驱动名前缀,例如:

>>> s = 'c:\\temp\\akarmi.txt'>>> print(os.path.splitext(s)[0])c:\temp\akarmi

所以因为我不需要驱动器号或目录名,我使用:

>>> print(os.path.splitext(os.path.basename(s))[0])akarmi

如果您想保留文件的路径并删除扩展名

>>> file = '/root/dir/sub.exten/file.data.1.2.dat'>>> print ('.').join(file.split('.')[:-1])/root/dir/sub.exten/file.data.1.2

我们可以做一些简单的split/pop魔术,如这里所示(https://stackoverflow.com/a/424006/1250044),以提取文件名(尊重Windows和POSIX差异)。

def getFileNameWithoutExtension(path):return path.split('\\').pop().split('/').pop().rsplit('.', 1)[0]
getFileNameWithoutExtension('/path/to/file-0.0.1.ext')# => file-0.0.1
getFileNameWithoutExtension('\\path\\to\\file-0.0.1.ext')# => file-0.0.1
import ospath = "a/b/c/abc.txt"print os.path.splitext(os.path.basename(path))[0]

如果扩展中有多个点,os.path.splitext()不会工作。

例如,images.tar.gz

>>> import os>>> file_path = '/home/dc/images.tar.gz'>>> file_name = os.path.basename(file_path)>>> print os.path.splitext(file_name)[0]images.tar

您可以只在基本名称中找到第一个点的索引,然后对基本名称进行切片以仅获得不带扩展名的文件名。

>>> import os>>> file_path = '/home/dc/images.tar.gz'>>> file_name = os.path.basename(file_path)>>> index_of_dot = file_name.index('.')>>> file_name_without_extension = file_name[:index_of_dot]>>> print file_name_without_extensionimages

为了方便起见,一个简单的函数包装了#0中的两个方法:

def filename(path):"""Return file name without extension from path.
See https://docs.python.org/3/library/os.path.html"""import os.pathb = os.path.split(path)[1]  # path, *filename*f = os.path.splitext(b)[0]  # *file*, ext#print(path, b, f)return f

使用Python 3.5测试。

import os

filename = C:\\Users\\Public\\Videos\\Sample Videos\\wildlife.wmv

这将返回没有extensionfilename(C:\用户\公共\视频\示例视频\野生动物)

temp = os.path.splitext(filename)[0]

现在你可以只从临时得到filename

os.path.basename(temp)   #this returns just the filename (wildlife)

正如@IceAdor在对@user2902201的解决方案的评论中指出的那样,rsplit是对多个句点健壮的最简单的解决方案(通过将拆分次数限制为仅1的maxsplit(从字符串末尾开始))。

以下是详细说明:

file = 'my.report.txt'print file.rsplit('.', maxsplit=1)[0]

my.report

import oslist = []def getFileName( path ):for file in os.listdir(path):#print filetry:base=os.path.basename(file)splitbase=os.path.splitext(base)ext = os.path.splitext(base)[1]if(ext):list.append(base)else:newpath = path+"/"+file#print pathgetFileName(newpath)except:passreturn list
getFileName("/home/weexcel-java3/Desktop/backup")print list

在Python 3.4+中,您可以使用#0解决方案

from pathlib import Path
print(Path(your_path).resolve().stem)

一个多扩展感知过程。适用于strunicode路径。适用于Python 2和3。

import os
def file_base_name(file_name):if '.' in file_name:separator_index = file_name.index('.')base_name = file_name[:separator_index]return base_nameelse:return file_name
def path_base_name(path):file_name = os.path.basename(path)return file_base_name(file_name)

行为规范:

>>> path_base_name('file')'file'>>> path_base_name(u'file')u'file'>>> path_base_name('file.txt')'file'>>> path_base_name(u'file.txt')u'file'>>> path_base_name('file.tar.gz')'file'>>> path_base_name('file.a.b.c.d.e.f.g')'file'>>> path_base_name('relative/path/file.ext')'file'>>> path_base_name('/absolute/path/file.ext')'file'>>> path_base_name('Relative\\Windows\\Path\\file.txt')'file'>>> path_base_name('C:\\Absolute\\Windows\\Path\\file.txt')'file'>>> path_base_name('/path with spaces/file.ext')'file'>>> path_base_name('C:\\Windows Path With Spaces\\file.txt')'file'>>> path_base_name('some/path/file name with spaces.tar.gz.zip.rar.7z')'file name with spaces'

解决这个问题最简单的方法是

import ntpathprint('Base name is ',ntpath.basename('/path/to/the/file/'))

这节省了您的时间和计算成本。

在Python 3.4+中使用#0 from#1

from pathlib import Path
Path('/root/dir/sub/file.ext').stem

将返回

'file'

请注意,如果您的文件有多个扩展名,.stem只会删除最后一个扩展名。例如,Path('file.tar.gz').stem将返回'file.tar'

我想我会在不需要使用数组索引的情况下使用os.path.splitext的变体。

该函数始终返回(root, ext)对,因此可以安全使用:

root, ext = os.path.splitext(path)

示例:

>>> import os>>> path = 'my_text_file.txt'>>> root, ext = os.path.splitext(path)>>> root'my_text_file'>>> ext'.txt'

https://docs.python.org/3/library/os.path.html

在python 3中,路径库模块提供了高级路径对象。所以

>>> from pathlib import Path
>>> p = Path("/a/b/c.txt")>>> p.with_suffix('')WindowsPath('/a/b/c')>>> p.stem'c'

其他方法不删除多个扩展名。有些还存在没有扩展名的文件名的问题。此代码段处理这两个实例并在Python 2和3中工作。它从路径中获取基名称,将值拆分为点,并返回第一个作为文件名的初始部分。

import os
def get_filename_without_extension(file_path):file_basename = os.path.basename(file_path)filename_without_extension = file_basename.split('.')[0]return filename_without_extension

下面是一组要运行的示例:

example_paths = ["FileName","./FileName","../../FileName","FileName.txt","./FileName.txt.zip.asc","/path/to/some/FileName","/path/to/some/FileName.txt","/path/to/some/FileName.txt.zip.asc"]
for example_path in example_paths:print(get_filename_without_extension(example_path))

在任何情况下,打印的值都是:

FileName
import osfilename, file_extension =os.path.splitext(os.path.basename('/d1/d2/example.cs'))
  • 文件名为“示例”

  • file_extension是. cs

'

非常非常非常简单没有其他模块!!!

import osp = r"C:\Users\bilal\Documents\face Recognition python\imgs\northon.jpg"
# Get the filename only from the initial file path.filename = os.path.basename(p)
# Use splitext() to get filename and extension separately.(file, ext) = os.path.splitext(filename)
# Print outcome.print("Filename without extension =", file)print("Extension =", ext)

我没有仔细看,但我没有看到有人使用regex来解决这个问题。

我将问题解释为“给定路径,返回不带扩展名的basename”。

e. g.

"path/to/file.json"=>"file"

"path/to/my.file.json"=>"my.file"

在Python 2.7中,我们仍然没有pathlib

def get_file_name_prefix(file_path):basename = os.path.basename(file_path)
file_name_prefix_match = re.compile(r"^(?P<file_name_pre fix>.*)\..*$").match(basename)
if file_name_prefix_match is None:return file_nameelse:return file_name_prefix_match.group("file_name_prefix")
get_file_name_prefix("path/to/file.json")>> file
get_file_name_prefix("path/to/my.file.json")>> my.file
get_file_name_prefix("path/to/no_extension")>> no_extension

使用Pathlib回答几个场景

使用Pathlib,当只有一个扩展名(或没有扩展名)时获取文件名是微不足道的,但处理多个扩展名的一般情况可能会很尴尬。

零或一扩展

from pathlib import Path
pth = Path('./thefile.tar')
fn = pth.stem
print(fn)      # thefile

# Explanation:# the `stem` attribute returns only the base filename, stripping# any leading path if present, and strips the extension after# the last `.`, if present.

# Further tests
eg_paths = ['thefile','thefile.tar','./thefile','./thefile.tar','../../thefile.tar','.././thefile.tar','rel/pa.th/to/thefile','/abs/path/to/thefile.tar']
for p in eg_paths:print(Path(p).stem)  # prints thefile every time

两个或更少的扩展

from pathlib import Path
pth = Path('./thefile.tar.gz')
fn = pth.with_suffix('').stem
print(fn)      # thefile

# Explanation:# Using the `.with_suffix('')` trick returns a Path object after# stripping one extension, and then we can simply use `.stem`.

# Further tests
eg_paths += ['./thefile.tar.gz','/abs/pa.th/to/thefile.tar.gz']
for p in eg_paths:print(Path(p).with_suffix('').stem)  # prints thefile every time

任意数量的扩展(0、1或更多)

from pathlib import Path
pth = Path('./thefile.tar.gz.bz.7zip')
fn = pth.nameif len(pth.suffixes) > 0:s = pth.suffixes[0]fn = fn.rsplit(s)[0]
# or, equivalently
fn = pth.namefor s in pth.suffixes:fn = fn.rsplit(s)[0]break
# or simply run the full loop
fn = pth.namefor _ in pth.suffixes:fn = fn.rsplit('.')[0]
# In any case:
print(fn)     # thefile

# Explanation## pth.name     -> 'thefile.tar.gz.bz.7zip'# pth.suffixes -> ['.tar', '.gz', '.bz', '.7zip']## If there may be more than two extensions, we can test for# that case with an if statement, or simply attempt the loop# and break after rsplitting on the first extension instance.# Alternatively, we may even run the full loop and strip one# extension with every pass.

# Further tests
eg_paths += ['./thefile.tar.gz.bz.7zip','/abs/pa.th/to/thefile.tar.gz.bz.7zip']
for p in eg_paths:pth = Path(p)fn = pth.namefor s in pth.suffixes:fn = fn.rsplit(s)[0]break
print(fn)  # prints thefile every time

已知第一个扩展的特殊情况

例如,如果扩展名可以是.tar.tar.gz.tar.gz.bz等;您可以简单地rsplit已知扩展名并获取第一个元素:

pth = Path('foo/bar/baz.baz/thefile.tar.gz')
fn = pth.name.rsplit('.tar')[0]
print(fn)      # thefile

改进@spinup答案:

fn = pth.namefor s in pth.suffixes:fn = fn.rsplit(s)[0]break    
print(fn)      # thefile

这也适用于没有扩展名的文件名

我已经阅读了答案,我注意到有很多好的解决方案。因此,对于那些希望获得(名称或扩展名)的人来说,这里有另一个解决方案,使用os模块,这两种方法都支持具有多个扩展名的文件。

import os
def get_file_name(path):if not os.path.isdir(path):return os.path.splitext(os.path.basename(path))[0].split(".")[0]

def get_file_extension(path):extensions = []copy_path = pathwhile True:copy_path, result = os.path.splitext(copy_path)if result != '':extensions.append(result)else:breakextensions.reverse()return "".join(extensions)

注意:Windows上的此解决方案不支持带有“\”字符的文件名

# use pathlib. the below works with compound filetypes and normal onessource_file = 'spaces.tar.gz.zip.rar.7z'source_path = pathlib.Path(source_file)source_path.name.replace(''.join(source_path.suffixes), '')>>> 'spaces'

尽管上面描述了许多工作实现,我还是添加了这个^,因为它只使用Pathlib并且适用于复合文件类型和正常文件类型

以下情况如何?

import pathlibfilename = '/path/to/dir/stem.ext.tar.gz'pathlib.Path(filename).name[:-len(''.join(pathlib.Path(filename).suffixes))]# -> 'stem'

还是这个等价物?

pathlib.Path(filename).name[:-sum(map(len, pathlib.Path(filename).suffixes))]

使用pathlib.Path.stem是正确的方法,但这里有一个丑陋的解决方案,它比基于Pathlib的方法更有效。

您有一个文件路径,其字段由正斜杠/分隔,斜杠不能出现在文件名中,因此您将文件路径拆分为/,最后一个字段是文件名。

扩展名始终是通过点.拆分文件名创建的列表的最后一个元素,因此如果您反转文件名并按点拆分一次,第二个元素的反转是没有扩展名的文件名。

name = path.split('/')[-1][::-1].split('.', 1)[1][::-1]

性能:

Python 3.9.10 (tags/v3.9.10:f2f3f53, Jan 17 2022, 15:14:21) [MSC v.1929 64 bit (AMD64)]Type 'copyright', 'credits' or 'license' for more informationIPython 7.28.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from pathlib import Path
In [2]: file = 'D:/ffmpeg/ffmpeg.exe'
In [3]: Path(file).stemOut[3]: 'ffmpeg'
In [4]: file.split('/')[-1][::-1].split('.', 1)[1][::-1]Out[4]: 'ffmpeg'
In [5]: %timeit Path(file).stem6.15 µs ± 433 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [6]: %timeit file.split('/')[-1][::-1].split('.', 1)[1][::-1]671 ns ± 37.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [7]:

>>>print(os.path.splitext(os.path.basename("/path/to/file/varun.txt"))[0]) varun

这里/path/to/file/varun.txt是文件的路径,输出是varun