Jak uzyskać nazwę pliku bez rozszerzenia ze ścieżki w Pythonie?

994

Jak uzyskać nazwę pliku bez rozszerzenia ze ścieżki w Pythonie?

Joan Venge
źródło

Odpowiedzi:

1314

Pobieranie nazwy pliku bez rozszerzenia:

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

Wydruki:

/path/to/some/file

Dokumentacja dlaos.path.splitext .

Ważna uwaga: jeśli nazwa pliku zawiera wiele kropek, usuwane jest tylko rozszerzenie po ostatniej. Na przykład:

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

Wydruki:

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

Zobacz inne odpowiedzi poniżej, jeśli chcesz poradzić sobie z tą sprawą.

Geo
źródło
13
Jeśli jest to dość powszechna operacja, być może powinna zasługiwać na swoje oficjalne polecenie? Coś takiego os.path.filename (ścieżka_dostępu_do_pliku) zamiast os.path.splitext (os.path.basename (ścieżka_dostępu_do_pliku)) [0]
Fnord
19
Co jeśli nazwa pliku zawiera wiele kropek?
matteok
100
Dla każdego, kto zastanawia się tak samo jak matteok, jeśli jest wiele kropek, splitext dzieli na ostatnim (tak splitext('kitty.jpg.zip')daje ('kitty.jpg', '.zip')).
Chuck,
50
Zauważ, że ten kod zwraca pełną ścieżkę pliku (bez rozszerzenia), a nie tylko nazwę pliku .
Aran-Fey
2
tak, więc musiałbyś to zrobić splitext(basename('/some/path/to/file.txt'))[0](co zawsze robię)
CpILL
531

Możesz tworzyć własne za pomocą:

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

Ważna uwaga: jeśli .w nazwie pliku znajduje się więcej niż jedna , usuwana jest tylko ostatnia. Na przykład:

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

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

Poniżej znajdują się inne odpowiedzi na to pytanie.

gimel
źródło
2
@ScottWilson: Jednak nadal musisz importować os.
LarsH
35
Co znaczy „rzuć to”?
LarsH
49
Jest skrótem od „roll your own”, co oznacza „zbuduj sam” w amerykańskim angielskim.
Scott C Wilson,
1
@Alan W. Smith, „Just roll it:” działał doskonale dobrze przez ostatnie 10 lat. Co znaczy „mniej amerykański”? Nie jestem za twoimi zmianami.
Logika1
4
edycja czyni to jaśniejszym. nie każdy ma angielski jako swój pierwszy język, więc powiedzenie czegoś takiego jak „rzuć to” może zwiększyć zamieszanie
nxmohamad
327

Używanie pathlibw Pythonie 3.4+

from pathlib import Path

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

wróci

'file'
pogrubienie
źródło
9
Jest to zalecany sposób od Pythona 3.
Miladiouss
1
Zauważ, że podobnie jak os.pathrozwiązania spowoduje to usunięcie tylko jednego rozszerzenia (lub suffix, jak pathlibto się nazywa). Path('a.b.c').stem == 'a.b'
BallpointBen
@BallpointBen jaki jest optymalny sposób usuwania wielu sufiksów? Na pewno musi być lepszy sposób niżPath(Path('a.b.c').stem).stem
Hoan
1
@hoan Myślę, że wielokrotne dzwonienie .with_suffix('')jest właściwą drogą. Prawdopodobnie chciałbyś zapętlić do p.suffix == ''.
BallpointBen
218
>>> print(os.path.splitext(os.path.basename("hemanth.txt"))[0])
hemanth
hemanth.hm
źródło
7
+1 za to. 3 dokładnie takie same odpowiedzi, ale ta jest najbardziej bezpośrednia. Po prostu mogłeś użyć `do wyświetlenia kodu i „/somepath/hermanth.txt” jako instancji ścieżki.
cregox
2
@ hemanth.hm Pamiętaj, że w tym oświadczeniu, które podałeś, os.path.basenamenie jest konieczne. os.path.basenamepowinien być używany tylko do uzyskania nazwy pliku ze ścieżki pliku.
arrt_
74

W Pythonie 3.4+ możesz użyć tego pathlibrozwiązania

from pathlib import Path

print(Path(your_path).resolve().stem)
Morgoth
źródło
4
Dlaczego jesteś resolve()ścieżką? Czy naprawdę jest możliwe uzyskanie ścieżki do pliku i bez tego, aby nazwa pliku nie była częścią ścieżki bez tego? Oznacza to, że jeśli podasz ścieżkę do dowiązania symbolicznego, zwrócisz nazwę pliku (bez rozszerzenia) pliku, na który wskazuje dowiązanie symboliczne.
Boris,
1
Jednym z możliwych powodów resolve()jest pomoc w rozwiązaniu problemu wielu kropek. Poniższa odpowiedź na temat korzystania z indeksu nie będzie działać, jeśli ścieżka to „./foo.tar.gz”
William Allcock
30

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

W python 3 pathlib „Moduł pathlib oferuje obiekty ścieżki wysokiego poziomu”. więc,

>>> from pathlib import Path
>>> p = Path("/a/b/c.txt")
>>> print(p.with_suffix(''))
\a\b\c
>>> print(p.stem)
c
jjisnow
źródło
1
Jest to najlepsze rozwiązanie dla Pythona 3 dla ogólnego przypadku usunięcia rozszerzenia z pełnej ścieżki. Użycie trzonu usuwa również ścieżkę nadrzędną. Jeśli oczekujesz podwójnego rozszerzenia (takiego jak bla.tar.gz), możesz go nawet użyć dwa razy: p.with_suffix (''). With_suffix ('').
Eelco van Vliet
24

Jeśli chcesz zachować ścieżkę do pliku i po prostu usuń rozszerzenie

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

źródło
16
Jeśli chcesz podzielić na ostatni okres, użyj rsplit:'/root/dir/sub.exten/file.data.1.2.dat'.rsplit('.', 1)
IceArdor
21

os.path.splitext () nie będzie działać, jeśli rozszerzenie ma wiele kropek.

Na przykład 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

Możesz po prostu znaleźć indeks pierwszej kropki w basenieame, a następnie pokroić basename, aby uzyskać tylko nazwę pliku bez rozszerzenia.

>>> 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
Dheeraj Chakravarthi
źródło
1
index_of_dot = nazwa_pliku.index ('.') Zostanie to zrobione po uzyskaniu nazwy basename pliku, aby nie dzielił się na .env
Chakravarthi
2
Ważna uwaga, ponieważ taka seria rozszerzeń jest powszechna. .tar.gz .tar.bz .tar.7z
2
Zauważ, że 'haystack'.index('needle')zgłasza wyjątek ValueError, jeśli igła (w powyższym przypadku kropka .) nie znajduje się w stogu siana. Istnieją również pliki bez żadnego rozszerzenia.
Czechnology
15

@ IceAdor's odnosi się do rsplit w komentarzu do rozwiązania @ user2902201. rsplit to najprostsze rozwiązanie, które obsługuje wiele okresów.

Tutaj jest napisane:

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

mój raport

dlink
źródło
13

Ale nawet gdy importuję system operacyjny, nie mogę nazwać go path.basename. Czy można to nazwać tak bezpośrednio jak basename?

import os, a następnie użyj os.path.basename

importing osnie oznacza, że ​​możesz używać os.foobez odwoływania się do os.

Devin Jeanpierre
źródło
1
chociaż jeśli chcesz zadzwonić bezpośrednio do foo, możesz użyć from os import foo.
tgray
masz bardzo niestandardową wersję osmodułu, jeśli ma on element o nazwie foo.
Tadhg McDonald-Jensen
2
To nazwa zastępcza. (np. rozważ path, lub walk).
Devin Jeanpierre,
13

Pomyślałem, że wrzucę wariant użycia os.path.splitext bez potrzeby korzystania z indeksowania tablic.

Funkcja zawsze zwraca (root, ext)parę, więc korzystanie z niej jest bezpieczne:

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

Przykład:

>>> import os
>>> path = 'my_text_file.txt'
>>> root, ext = os.path.splitext(path)
>>> root
'my_text_file'
>>> ext
'.txt'
ScottMcC
źródło
os.path.splittext () to wersja
3.6+
6

Inne metody nie usuwają wielu rozszerzeń. Niektóre mają również problemy z nazwami plików, które nie mają rozszerzeń. Ten fragment dotyczy obu instancji i działa zarówno w Pythonie 2, jak i 3. Pobiera basename ze ścieżki, dzieli wartość na kropki i zwraca pierwszą, która jest początkową częścią nazwy pliku.

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

Oto zestaw przykładów do uruchomienia:

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

W każdym przypadku drukowana wartość to:

FileName
Alan W. Smith
źródło
Poza wartością dodaną związaną z obsługą wielu kropek, ta metoda jest znacznie szybsza niż Path('/path/to/file.txt').stem. (1,23μs vs 8,39μs)
raratiru
To nie działa dla nazwy pliku nvdcve-1.1-2002.json.zip
Michele
Podzieliłem go na fileBasename.split ('. Json') [0] i zadziałało
Michele
4

import os

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

Zwraca to filenamebez extension(C: \ Users \ Public \ Videos \ Sample Videos \ wildlife)

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

Teraz możesz uzyskać tylko filenamez temp. Z

os.path.basename(temp)   #this returns just the filename (wildlife)
learncode
źródło
3

Procedura uwzględniająca wiele rozszerzeń. Działa stri unicodeścieżki. Działa w Python 2 i 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)

Zachowanie:

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

źródło
1
import os
path = "a/b/c/abc.txt"
print os.path.splitext(os.path.basename(path))[0]
użytkownik4949344
źródło
0

W systemie Windows użyłem również prefiksu nazwy sterownika, takiego jak:

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

Ponieważ nie potrzebuję litery dysku ani nazwy katalogu, używam:

>>> print(os.path.splitext(os.path.basename(s))[0])
akarmi
Zéiksz
źródło
0

Dla wygody prosta funkcja owijająca dwie metody z 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

Testowane z Python 3.5.

uchwyt
źródło
0

najprostszym sposobem rozwiązania tego jest

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

oszczędza to czas i koszty obliczeń.

Nkoro Joseph Ahamefula
źródło
0

Bardzo, bardzo, bardzo prosto, żadnych innych modułów !!!

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)
Bilal
źródło
-1

Możemy zrobić trochę prostego split/ popmagicznego pokazanego tutaj ( https://stackoverflow.com/a/424006/1250044 ), aby wyodrębnić nazwę pliku (uwzględniając różnice między oknami i 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
yckart
źródło
os.path.splitext () [0] robi to samo.
Charles Plager
@CharlesPlager os.path.splitext () nie będzie działać, jeśli rozszerzenie ma wiele kropek. stackoverflow.com/a/37760212/1250044
yckart 13.09.16
To działa dla mnie: w [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
shivendra singh
źródło
-3

import os nazwa pliku, file_extension = os.path.splitext ('/ d1 / d2 / example.cs') nazwa pliku to '/ d1 / d2 / example' file_extension to '.cs'

Antonio Ramasco
źródło