Làm cách nào để có được tên tệp mà không có phần mở rộng từ một đường dẫn trong Python?


995

Làm cách nào để có được tên tệp mà không có phần mở rộng từ một đường dẫn trong Python?

Câu trả lời:


1316

Lấy tên của tệp mà không cần phần mở rộng:

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

Bản in:

/path/to/some/file

Tài liệu choos.path.splitext .

Lưu ý quan trọng: Nếu tên tệp có nhiều dấu chấm, chỉ phần mở rộng sau phần cuối cùng bị xóa. Ví dụ:

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

Bản in:

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

Xem các câu trả lời khác dưới đây nếu bạn cần xử lý trường hợp đó.


13
Nếu đây là một hoạt động đủ phổ biến, có lẽ nó nên xứng đáng với lệnh chính thức của nó? Một cái gì đó như os.path.filename (path_to_file) thay vì os.path.splitext (os.path.basename (path_to_file)) [0]
Fnord

19
Nếu tên tệp chứa nhiều dấu chấm thì sao?
mattok

101
Đối với bất kỳ ai thắc mắc tương tự như mattok, nếu có nhiều dấu chấm, splitext sẽ tách ra ở điểm cuối cùng (vì vậy splitext('kitty.jpg.zip')sẽ cho ('kitty.jpg', '.zip')).
Chuck

50
Lưu ý rằng mã này trả về đường dẫn tệp hoàn chỉnh (không có phần mở rộng), không chỉ tên tệp .
Aran-Fey

2
vâng, vì vậy bạn sẽ phải làm splitext(basename('/some/path/to/file.txt'))[0](điều mà tôi dường như luôn luôn làm)
CpILL

531

Bạn có thể làm cho riêng mình với:

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

Lưu ý quan trọng: Nếu có nhiều hơn một .trong tên tệp, chỉ có cái cuối cùng bị xóa. Ví dụ:

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

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

Xem dưới đây cho câu trả lời khác giải quyết rằng.


2
@ScottWilson: Bạn vẫn phải nhập osmặc dù.
LarsH

35
"Cuộn nó" nghĩa là gì?
LarsH

50
Nó là viết tắt của "roll your own", có nghĩa là "tự mình xây dựng" bằng tiếng Anh Mỹ.
Scott C Wilson

2
@Alan W. Smith, "Chỉ cần cuộn nó:" đã hoạt động hoàn toàn tốt trong 10 năm qua. "Ít người Mỹ" nghĩa là gì? Tôi không ủng hộ các chỉnh sửa của bạn.
Logic1

4
chỉnh sửa làm cho nó rõ ràng hơn. không phải ai cũng có tiếng Anh là ngôn ngữ đầu tiên của họ, vì vậy việc nói một cái gì đó như 'cuộn nó' có thể gây thêm nhầm lẫn
nxmohamad

327

Sử dụng pathlibtrong Python 3.4+

from pathlib import Path

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

sẽ trở lại

'file'

9
Đây là cách được đề xuất kể từ python 3.
Miladiouss

1
Lưu ý rằng, giống như os.pathcác giải pháp, điều này sẽ chỉ loại bỏ một phần mở rộng (hoặc suffix, như cách pathlibgọi nó). Path('a.b.c').stem == 'a.b'
BallpointBen

@BallpointBen cách tối ưu để tước nhiều hậu tố là gì? Chắc chắn phải có một cách tốt hơnPath(Path('a.b.c').stem).stem
Hoàn

1
@hoan Tôi nghĩ liên tục gọi điện .with_suffix('')là cách để đi. Bạn có thể muốn lặp lại cho đến khi p.suffix == ''.
BallpointBen

218
>>> print(os.path.splitext(os.path.basename("hemanth.txt"))[0])
hemanth

7
+1 cho điều này. 3 câu trả lời chính xác giống nhau, nhưng đây là câu trả lời trực tiếp nhất. Bạn chỉ có thể đã được sử dụng `để hiển thị mã và "/somepath/hermanth.txt" làm ví dụ đường dẫn.
cregox

2
@ hemanth.hm Lưu ý rằng trong tuyên bố này bạn đã cung cấp, os.path.basenamekhông cần thiết. os.path.basenamechỉ nên được sử dụng để lấy tên tệp từ đường dẫn tệp.
arrt_

74

Trong Python 3.4+, bạn có thể sử dụng pathlibgiải pháp

from pathlib import Path

print(Path(your_path).resolve().stem)

4
Tại sao bạn resolve()là con đường? Có thực sự có thể có được một đường dẫn đến một tập tin và không có tên tệp là một phần của đường dẫn mà không có điều đó? Điều này có nghĩa là nếu bạn đưa ra một đường dẫn đến symlink, bạn sẽ trả lại tên tệp (không có phần mở rộng) của tệp mà symlink trỏ tới.
Boris

1
Một lý do có thể sử dụng resolve()là để giúp giải quyết vấn đề nhiều dấu chấm. Câu trả lời bên dưới về việc sử dụng chỉ mục sẽ không hoạt động nếu đường dẫn là './foo.tar.gz'
William Allcock

30

https://docs.python.org/3/l Library / os.path.html

Trong python 3 pathlib "Mô-đun pathlib cung cấp các đối tượng đường dẫn mức cao." vì thế,

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

1
Đây là giải pháp python 3 tốt nhất cho trường hợp chung loại bỏ phần mở rộng khỏi đường dẫn đầy đủ. Sử dụng thân cây cũng loại bỏ đường dẫn cha mẹ. Trong trường hợp bạn đang mong đợi một tiện ích mở rộng gấp đôi (chẳng hạn như bla.tar.gz) thì bạn thậm chí có thể sử dụng hai lần: p.with_suffix (''). With_suffix ('').
Eelco van Vliet

24

Nếu bạn muốn giữ đường dẫn đến tệp và chỉ cần xóa phần mở rộng

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

16
Nếu bạn muốn tách vào khoảng thời gian cuối cùng, hãy sử dụng rsplit:'/root/dir/sub.exten/file.data.1.2.dat'.rsplit('.', 1)
IceArdor

21

os.path.splitext () sẽ không hoạt động nếu có nhiều dấu chấm trong phần mở rộng.

Ví dụ: hình ảnh.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

Bạn chỉ có thể tìm thấy chỉ mục của dấu chấm đầu tiên trong tên cơ sở và sau đó cắt tên cơ sở để chỉ lấy tên tệp mà không cần mở rộng.

>>> 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_extension
images

1
index_of_dot = file_name.index ('.') Điều này sẽ được thực hiện sau khi lấy tên cơ sở của tệp để nó không bị phân tách tại .env
Dheeraj Chakravarthi

2
Điểm quan trọng, vì một loạt các phần mở rộng như thế này là phổ biến. .tar.gz .tar.bz .tar.7z

2
Lưu ý rằng 'haystack'.index('needle')sẽ ném ngoại lệ ValueError nếu .không tìm thấy kim (trong trường hợp trên là dấu chấm ) trong haystack. Các tập tin không có bất kỳ phần mở rộng tồn tại quá.
Công nghệ

15

@ IceAdor đề cập đến rsplit trong một bình luận cho giải pháp của @ user2902201. rsplit là giải pháp đơn giản nhất hỗ trợ nhiều thời kỳ.

Ở đây nó được đánh vần:

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

my.report


13

Nhưng ngay cả khi tôi nhập os, tôi không thể gọi nó là path.basename. Có thể gọi nó là trực tiếp như tên cơ sở?

import osvà sau đó sử dụng os.path.basename

importing oskhông có nghĩa là bạn có thể sử dụng os.foomà không cần tham khảo os.


1
mặc dù nếu bạn muốn gọi trực tiếp cho foo, bạn có thể sử dụng from os import foo.
tgray

bạn có một phiên bản rất không chuẩn của osmô-đun nếu nó có một thành viên được gọi foo.
Tadhg McDonald-Jensen

2
Đó là một tên giữ chỗ. (ví dụ path, xem xét , hoặc walk).
Devin Jeanpierre

13

Nghĩ rằng tôi sẽ sử dụng os.path.splitext mà không cần sử dụng lập chỉ mục mảng.

Hàm luôn trả về một (root, ext)cặp để sử dụng an toàn:

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

Thí dụ:

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

os.path.splittext () là Phiên bản
3.6+

6

Các phương pháp khác không xóa nhiều tiện ích mở rộng. Một số cũng có vấn đề với tên tệp không có phần mở rộng. Đoạn mã này xử lý cả hai phiên bản và hoạt động trong cả Python 2 và 3. Nó lấy tên cơ sở từ đường dẫn, chia giá trị trên các dấu chấm và trả về cái đầu tiên là phần đầu tiên của tên tệp.

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

Đây là một tập hợp các ví dụ để chạy:

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))

Trong mọi trường hợp, giá trị được in là:

FileName

Ngoại trừ giá trị gia tăng của việc xử lý nhiều dấu chấm, phương pháp này nhanh hơn nhiều so với Path('/path/to/file.txt').stem. (1,23μs so với 8,39μs)
raratiru

Điều này không hoạt động cho tên tệp nvdcve-1.1-2002.json.zip
Michele

Tôi chia nó trên fileBasename.split ('. Json') [0] và nó đã hoạt động
Michele

4

import os

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

Điều này trả về filenamemà không có extension(C: \ Users \ Public \ Video \ Video mẫu \ động vật hoang dã)

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

Bây giờ bạn có thể nhận được chỉ filenametừ temp với

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

3

Một thủ tục nhận thức nhiều phần mở rộng. Hoạt động cho strunicodeđường dẫn. Hoạt động trong Python 2 và 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_name
    else:
        return file_name

def path_base_name(path):
    file_name = os.path.basename(path)
    return file_base_name(file_name)

Hành vi:

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


0

Trên hệ thống Windows, tôi cũng sử dụng tiền tố tên trình điều khiển, như:

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

Vì vậy, vì tôi không cần tên ổ đĩa hoặc tên thư mục, tôi sử dụng:

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

0

Để thuận tiện, một hàm đơn giản bao gồm hai phương thức từ os.path:

def filename(path):
  """Return file name without extension from path.

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

Đã thử nghiệm với Python 3.5.


0

cách dễ nhất để giải quyết điều này là

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

Điều này giúp bạn tiết kiệm thời gian và chi phí tính toán.


0

Rất rất rất rất đơn giản không có mô-đun nào khác !!!

import os
p = 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)

-1

Chúng ta có thể làm một số đơn giản split/ popkỳ diệu như đã thấy ở đây ( https://stackoverflow.com/a/424006/1250044 ), để trích xuất các tên tập tin (tôn trọng các cửa sổ và sự khác biệt 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

os.path.splitext () [0] cũng làm điều tương tự.
Charles Plager

@CharlesPlager os.path.splitext () sẽ không hoạt động nếu có nhiều dấu chấm trong tiện ích mở rộng. stackoverflow.com/a/37760212/1250044
yckart

Nó hoạt động với tôi: Trong [72]: os.path.splitext ('one.two.three.ext') Out [72]: ('one.two.three', '.ext')
Charles Plager

-1
import os
list = []
def getFileName( path ):
for file in os.listdir(path):
    #print file
    try:
        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 path
            getFileName(newpath)
    except:
        pass
return list

getFileName("/home/weexcel-java3/Desktop/backup")
print list

-3

nhập tên tệp os, file_extension = os.path.splitext ('/ d1 / d2 / example.cs') tên tệp là '/ d1 / d2 / example' file_extension là '.cs'

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.