Comment obtenir le nom de fichier sans l'extension à partir d'un chemin en Python?


996

Comment obtenir le nom de fichier sans l'extension à partir d'un chemin en Python?

Réponses:


1317

Obtenir le nom du fichier sans l'extension:

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

Tirages:

/path/to/some/file

Documentation pouros.path.splitext .

Remarque importante: si le nom de fichier comporte plusieurs points, seule l'extension après le dernier est supprimée. Par exemple:

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

Tirages:

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

Voir les autres réponses ci-dessous si vous devez gérer ce cas.


13
Si c'est une opération assez courante, peut-être devrait-elle mériter sa propre commande officielle? Quelque chose comme os.path.filename (path_to_file) au lieu de os.path.splitext (os.path.basename (path_to_file)) [0]
Fnord

19
Que faire si le nom de fichier contient plusieurs points?
matteok

101
Pour quiconque se demande la même chose que matteok, s'il y a plusieurs points, splitext se divise au dernier (donc splitext('kitty.jpg.zip')donne ('kitty.jpg', '.zip')).
Chuck

50
Notez que ce code renvoie le chemin d'accès complet au fichier (sans l'extension), pas seulement le nom du fichier .
Aran-Fey

2
ouais, donc tu devrais le faire splitext(basename('/some/path/to/file.txt'))[0](ce que j'ai toujours l' air de faire)
CpILL

532

Vous pouvez créer le vôtre avec:

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

Remarque importante: s'il y en a plusieurs .dans le nom de fichier, seul le dernier est supprimé. Par exemple:

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

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

Voir ci-dessous pour d'autres réponses qui répondent à cela.


2
@ScottWilson: Vous devez quand même importer os.
LarsH

35
Que signifie «rouler»?
LarsH

50
C'est l'abréviation de "roll your own", qui signifie "build it yourself" en anglais américain.
Scott C Wilson

2
@Alan W. Smith, "Just roll it:" fonctionnait parfaitement bien depuis 10 ans. Que signifie «moins américain»? Je ne suis pas en faveur de vos modifications.
Logic1

4
le montage le rend plus clair. tout le monde n'a pas l'anglais comme première langue, donc dire quelque chose comme «roll it» pourrait ajouter à la confusion
nxmohamad

327

Utilisation pathlibdans Python 3.4+

from pathlib import Path

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

reviendra

'file'

9
C'est la voie recommandée depuis python 3.
Miladiouss

1
Notez que, comme les os.pathsolutions, cela ne supprimera qu'une seule extension (ou suffix, comme l' pathlibappelle). Path('a.b.c').stem == 'a.b'
BallpointBen

@BallpointBen quelle est la façon optimale de supprimer plusieurs suffixes? Il doit sûrement y avoir un meilleur moyen quePath(Path('a.b.c').stem).stem
hoan

1
@hoan Je pense qu'appeler à plusieurs reprises .with_suffix('')est la voie à suivre. Vous voudrez probablement boucler jusqu'à p.suffix == ''.
BallpointBen

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

7
+1 pour cela. 3 exactement les mêmes réponses, mais c'est la plus directe. Vous auriez juste pu utiliser `pour afficher le code et "/somepath/hermanth.txt" comme instance de chemin.
cregox

2
@ hemanth.hm Notez que dans cette déclaration que vous avez fournie, os.path.basenamen'est pas nécessaire. os.path.basenamene doit être utilisé que pour obtenir le nom du fichier à partir du chemin du fichier.
arrt_

74

Dans Python 3.4+, vous pouvez utiliser la pathlibsolution

from pathlib import Path

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

4
Pourquoi avez-vous resolve()le chemin? Est-il vraiment possible d'obtenir un chemin d'accès à un fichier sans que le nom de fichier fasse partie du chemin sans cela? Cela signifie que si vous donnez un chemin vers le lien symbolique, vous retournerez le nom de fichier (sans l'extension) du fichier vers lequel le lien symbolique pointe.
Boris

1
Une raison possible d'utiliser resolve()est d'aider à résoudre le problème des points multiples. La réponse ci-dessous sur l'utilisation de l'index ne fonctionnera pas si le chemin est './foo.tar.gz'
William Allcock

30

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

En python 3 pathlib "Le module pathlib propose des objets de chemin de haut niveau." donc,

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

1
Il s'agit de la meilleure solution python 3 pour le cas générique de suppression de l'extension d'un chemin complet. L'utilisation de stem supprime également le chemin parent. Dans le cas où vous vous attendez à une double extension (telle que bla.tar.gz), vous pouvez même l'utiliser deux fois: p.with_suffix (''). With_suffix ('').
Eelco van Vliet

24

Si vous souhaitez conserver le chemin d'accès au fichier et simplement supprimer l'extension

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

16
Si vous voulez partager sur la dernière période, utilisez rsplit:'/root/dir/sub.exten/file.data.1.2.dat'.rsplit('.', 1)
IceArdor

21

os.path.splitext () ne fonctionnera pas s'il y a plusieurs points dans l'extension.

Par exemple, 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

Vous pouvez simplement trouver l'index du premier point dans le nom de base, puis couper le nom de base pour obtenir uniquement le nom de fichier sans extension.

>>> 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 ('.') Cela sera fait après avoir obtenu le nom de base du fichier afin qu'il ne se divise pas en .env
Dheeraj Chakravarthi

2
Point important, car une série d'extensions comme celle-ci est courante. .tar.gz .tar.bz .tar.7z

2
Notez que 'haystack'.index('needle')lève une exception ValueError si l'aiguille (dans le cas ci-dessus le point, .) n'est pas trouvée dans la botte de foin. Des fichiers sans extension existent également.
Czechnology

15

@ IceAdor fait référence à rsplit dans un commentaire sur la solution de @ user2902201. rsplit est la solution la plus simple qui prend en charge plusieurs périodes.

Ici, il est énoncé:

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

mon rapport


13

Mais même lorsque j'importe os, je ne peux pas l'appeler path.basename. Est-il possible de l'appeler aussi directement que nom de base?

import os, puis utilisez os.path.basename

importing osne signifie pas que vous pouvez utiliser os.foosans vous y référer os.


1
si vous voulez appeler directement foo, vous pouvez utiliser from os import foo.
tgray

vous avez une version très non standard du osmodule si un membre est appelé foo.
Tadhg McDonald-Jensen

2
C'est un nom d'espace réservé. (par exemple, envisagez path, ou walk).
Devin Jeanpierre

13

Je pensais que je voudrais apporter une variation à l'utilisation de os.path.splitext sans avoir besoin d'utiliser l'indexation de tableaux.

La fonction renvoie toujours une (root, ext)paire, il est donc sûr de l'utiliser:

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

Exemple:

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

os.path.splittext () est la version 3.6+
Yzmir Ramirez

6

Les autres méthodes ne suppriment pas plusieurs extensions. Certains ont également des problèmes avec les noms de fichiers qui n'ont pas d'extensions. Cet extrait traite des deux instances et fonctionne à la fois en Python 2 et 3. Il récupère le nom de base du chemin, divise la valeur en points et renvoie la première qui est la partie initiale du nom de fichier.

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

Voici un ensemble d'exemples à exécuter:

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

Dans tous les cas, la valeur imprimée est:

FileName

À l'exception de la valeur ajoutée de la gestion de plusieurs points, cette méthode est beaucoup plus rapide que Path('/path/to/file.txt').stem. (1,23 μs vs 8,39 μs)
raratiru

Cela ne fonctionne pas pour le nom de fichier nvdcve-1.1-2002.json.zip
Michele

Je l'ai divisé sur fileBasename.split ('. Json') [0] et cela a fonctionné
Michele

4

import os

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

Cela renvoie le filenamesans le extension(C: \ Users \ Public \ Videos \ Sample Videos \ Wildlife)

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

Maintenant, vous pouvez obtenir juste filenamede la température avec

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

3

Une procédure compatible avec plusieurs extensions. Fonctionne pour stret unicodechemins. Fonctionne en Python 2 et 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)

Comportement:

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

1
import os
path = "a/b/c/abc.txt"
print os.path.splitext(os.path.basename(path))[0]

0

Sur le système Windows, j'ai également utilisé le préfixe de nom de pilote, comme:

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

Donc, parce que je n'ai pas besoin de lettre de lecteur ou de nom de répertoire, j'utilise:

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

0

Pour plus de commodité, une fonction simple encapsulant les deux méthodes de 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

Testé avec Python 3.5.


0

la façon la plus simple de résoudre ce problème est de

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

cela vous fait gagner du temps et des coûts de calcul.


0

Très très très simplement aucun autre module !!!

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

Nous pourrions faire un peu de magie split/ popcomme on le voit ici ( https://stackoverflow.com/a/424006/1250044 ), pour extraire le nom de fichier (en respectant les fenêtres et les différences 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] fait la même chose.
Charles Plager

@CharlesPlager os.path.splitext () ne fonctionnera pas s'il y a plusieurs points dans l'extension. stackoverflow.com/a/37760212/1250044
yckart

Cela fonctionne pour moi: In [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

import os filename, file_extension = os.path.splitext ('/ d1 / d2 / example.cs') nom de fichier est '/ d1 / d2 / exemple' file_extension is '.cs'

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.