จะรับชื่อไฟล์ที่ไม่มีนามสกุลจากพา ธ ใน Python ได้อย่างไร


คำตอบ:


1315

รับชื่อไฟล์โดยไม่มีนามสกุล:

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

พิมพ์:

/path/to/some/file

os.path.splitextเอกสาร

หมายเหตุสำคัญ:หากชื่อไฟล์มีหลายจุดเฉพาะส่วนขยายหลังจากนามสกุลสุดท้ายจะถูกลบออก ตัวอย่างเช่น:

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

พิมพ์:

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

ดูคำตอบอื่น ๆ ด้านล่างหากคุณต้องการจัดการกับกรณีดังกล่าว


13
หากนี่เป็นการดำเนินการที่ธรรมดาพอสมควรบางทีมันควรจะทำมันเป็นคำสั่งอย่างเป็นทางการ บางอย่างเช่น os.path.filename (path_to_file) แทน os.path.splitext (os.path.basename (path_to_file)) [0]
Fnord

19
เกิดอะไรขึ้นถ้าชื่อไฟล์มีหลายจุด
matteok

100
สำหรับทุกคนที่สงสัยเช่นเดียวกับ matteok หากมีหลายจุด Splitext จะแยกที่จุดสุดท้าย (ดังนั้นsplitext('kitty.jpg.zip')จะให้('kitty.jpg', '.zip'))
Chuck

50
โปรดทราบว่ารหัสนี้จะส่งกลับไฟล์ที่สมบูรณ์เส้นทาง (ไม่มีนามสกุล) ไม่เพียง แต่ไฟล์ชื่อ
Aran-Fey

2
ใช่คุณต้องทำsplitext(basename('/some/path/to/file.txt'))[0](ซึ่งฉันมักจะทำ)
CpILL

531

คุณสามารถสร้างของคุณเองด้วย:

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

ดูคำตอบอื่น ๆ ที่อยู่ด้านล่าง


2
@ScottWilson: คุณยังคงต้องนำเข้าosแต่
LarsH

35
'ม้วน' หมายความว่าอย่างไร
LarsH

49
มันสั้นสำหรับ "ม้วนตัวคุณเอง" ซึ่งหมายความว่า "สร้างมันเอง" ในภาษาอังกฤษแบบอเมริกัน
Scott C Wilson

1
@ Alan W. Smith, "Just roll it:" ทำงานได้อย่างสมบูรณ์แบบในช่วง 10 ปีที่ผ่านมา "น้อยกว่าอเมริกัน" หมายความว่าอะไร? ฉันไม่ชอบการแก้ไขของคุณ
Logic1

4
การแก้ไขทำให้ชัดเจนยิ่งขึ้น ไม่ใช่ทุกคนที่มีภาษาอังกฤษเป็นภาษาแรกดังนั้นการพูดว่า 'roll it' สามารถเพิ่มความสับสนได้
nxmohamad

327

ใช้pathlibใน Python 3.4+

from pathlib import Path

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

จะกลับมา

'file'

9
นี่เป็นวิธีที่แนะนำตั้งแต่ python 3
Miladiouss

1
โปรดทราบว่าเช่นเดียวกับos.pathการแก้ปัญหานี้จะตัดเฉพาะส่วนขยาย (หรือsuffixเป็นpathlibสายมัน) Path('a.b.c').stem == 'a.b'
BallpointBen

@BallpointBen วิธีที่ดีที่สุดในการลอกส่วนต่อท้ายหลายรายการคืออะไร แน่นอนว่าจะต้องมีวิธีที่ดีกว่าPath(Path('a.b.c').stem).stem
hoan

1
@hoan ฉันคิดว่าการโทรซ้ำ ๆ.with_suffix('')เป็นวิธีที่จะไป p.suffix == ''คุณอาจต้องการที่จะห่วงจน
BallpointBen

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

7
+1 สำหรับสิ่งนี้ 3 คำตอบที่เหมือนกันทุกประการ แต่นี่เป็นคำตอบที่ตรงที่สุด คุณสามารถใช้`เพื่อแสดงรหัสและ "/somepath/hermanth.txt" เป็นอินสแตนซ์ของเส้นทาง
cregox

2
@ hemanth.hm โปรดทราบว่าในข้อความนี้ที่คุณระบุos.path.basenameไม่จำเป็นต้องมี os.path.basenameควรใช้เพื่อรับชื่อไฟล์จากพา ธ ไฟล์เท่านั้น
arrt_

74

ใน Python 3.4+ คุณสามารถใช้pathlibวิธีแก้ปัญหาได้

from pathlib import Path

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

4
ทำไมคุณresolve()ถึงเส้นทาง เป็นไปได้จริง ๆ ที่จะได้รับพา ธ ไปยังไฟล์และไม่มีชื่อไฟล์เป็นส่วนหนึ่งของพา ธ โดยที่ไม่มีหรือไม่? ซึ่งหมายความว่าหากคุณให้เส้นทางไปยัง symlink คุณจะส่งคืนชื่อไฟล์ (โดยไม่มีส่วนขยาย) ของไฟล์ที่ symlink ชี้ไป
บอริส

1
เหตุผลหนึ่งที่เป็นไปได้ที่จะใช้resolve()คือช่วยจัดการกับปัญหาหลายจุด คำตอบด้านล่างเกี่ยวกับการใช้ดัชนีจะไม่ทำงานหากเส้นทางคือ './foo.tar.gz'
William Allcock

30

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

ใน python 3 pathlib "โมดูล pathlib เสนอวัตถุพา ธ ระดับสูง" ดังนั้น,

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

1
นี่เป็นทางออกที่ดีที่สุดของ python 3 สำหรับกรณีทั่วไปของการลบส่วนขยายออกจากเส้นทางแบบเต็ม การใช้สเต็มยังลบพา ธ พาเรนต์ ในกรณีที่คุณคาดว่าจะมีนามสกุลเป็นสองเท่า (เช่น bla.tar.gz) คุณสามารถใช้สองครั้งได้ด้วย: p.with_suffix (''). with_suffix ('')
Eelco van Vliet

24

หากคุณต้องการเก็บเส้นทางไปยังไฟล์และเพียงแค่ลบนามสกุล

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

16
หากคุณต้องการแยกช่วงเวลาสุดท้ายให้ใช้ rsplit:'/root/dir/sub.exten/file.data.1.2.dat'.rsplit('.', 1)
IceArdor

21

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

1
index_of_dot = file_name.index ('.') สิ่งนี้จะทำหลังจากได้รับชื่อไฟล์พื้นฐานเพื่อที่จะไม่แยกที่. env
Dheeraj Chakravarthi

2
จุดสำคัญเนื่องจากชุดของส่วนขยายเช่นนี้เป็นเรื่องปกติ .tar.gz .tar.bz .tar.7z

2
โปรดทราบว่าจะ'haystack'.index('needle')ส่งข้อยกเว้น ValueError หาก.ไม่พบเข็ม (ในกรณีข้างต้นคือจุด, ) ในกองหญ้า ไฟล์ที่ไม่มีนามสกุลก็มีเช่นกัน
Czechnology

15

@ IceAdor's หมายถึง rsplit ในความคิดเห็นถึงโซลูชั่นของ @ user2902201 rsplit เป็นวิธีที่ง่ายที่สุดที่รองรับหลายช่วงเวลา

นี่มันสะกดออกมา:

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

my.report


13

แต่แม้ว่าฉันจะนำเข้าระบบปฏิบัติการฉันก็ไม่สามารถเรียกมันว่า path.basename เป็นไปได้หรือไม่ที่จะเรียกมันว่าโดยตรงเป็นชื่อฐาน?

import osและจากนั้นใช้ os.path.basename

importไอเอ็นจีosไม่ได้หมายความว่าคุณสามารถใช้โดยไม่ได้หมายถึงos.fooos


1
แม้ว่าคุณต้องการโทรหา foo โดยตรงคุณก็สามารถfrom os import fooใช้ได้
tgray

คุณมีรุ่นที่ไม่ได้มาตรฐานมากของโมดูลถ้ามีสมาชิกคนหนึ่งเรียกว่าos foo
Tadhg McDonald-Jensen

2
มันเป็นชื่อตัวแทน (เช่นพิจารณาpathหรือwalk)
Devin Jeanpierre

13

คิดว่าฉันจะโยนรูปแบบการใช้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'

os.path.splittext () คือเวอร์ชั่น 3.6+
Yzmir Ramirez

6

วิธีอื่นไม่ได้ลบส่วนขยายหลายรายการ บางคนมีปัญหากับชื่อไฟล์ที่ไม่มีส่วนขยาย ตัวอย่างนี้เกี่ยวข้องกับทั้งสองอินสแตนซ์และใช้งานได้ทั้ง 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

Path('/path/to/file.txt').stemยกเว้นสำหรับการเพิ่มมูลค่าของการจัดการจุดหลายวิธีนี้เป็นวิธีที่รวดเร็วกว่า (1,23μs vs 8.39μs)
raratiru

สิ่งนี้ใช้ไม่ได้กับชื่อไฟล์ nvdcve-1.1-2002.json.zip
Michele

ฉันแยกมันไว้ที่ fileBasename.split ('. json') [0] และมันใช้งานได้
Michele

4

import os

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

สิ่งนี้จะคืนค่าที่filenameไม่มีextension(C: \ Users \ Public \ Videos \ Sample Videos \ wildlife)

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

ตอนนี้คุณสามารถได้รับเพียงfilenameจากอุณหภูมิด้วย

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

3

โพรซีเดอร์การรับรู้ส่วนขยายจำนวนมาก ผลงานstrและunicodeเส้นทาง ใช้งานได้ใน 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_name
    else:
        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'


0

ในระบบ 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

0

เพื่อความสะดวกของฟังก์ชั่นที่เรียบง่ายห่อสองวิธีจาก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

ทดสอบกับ Python 3.5


0

วิธีที่ง่ายที่สุดในการแก้ไขปัญหานี้คือ

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

ช่วยประหยัดเวลาและค่าใช้จ่ายในการคำนวณ


0

อย่างมากมากมากไม่มีโมดูลอื่น ๆ !!!

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

เราสามารถทำอะไรง่าย ๆsplit/ popเวทมนต์ตามที่เห็นที่นี่ ( https://stackoverflow.com/a/424006/1250044 ) เพื่อแยกชื่อไฟล์ (ตามหน้าต่างและความแตกต่าง 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] ทำสิ่งเดียวกัน
Charles Plager

@CharlesPlager os.path.splitext () จะไม่ทำงานหากมีหลายจุดในส่วนขยาย stackoverflow.com/a/37760212/1250044
yckart

มันใช้งานได้สำหรับฉัน: ใน [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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.