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?

Joan Venge
la source

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.

Géo
la source
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.

gimel
la source
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'
audacieux
la source
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
hemanth.hm
la source
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)
Morgoth
la source
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
jjisnow
la source
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

la source
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
Dheeraj Chakravarthi
la source
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

dlink
la source
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.

Devin Jeanpierre
la source
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'
ScottMcC
la source
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
Alan W. Smith
la source
À 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)
learncode
la source
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'

la source
1
import os
path = "a/b/c/abc.txt"
print os.path.splitext(os.path.basename(path))[0]
user4949344
la source
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
Zéiksz
la source
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.

manipuler
la source
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.

Nkoro Joseph Ahamefula
la source
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)
Bilal
la source
-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
yckart
la source
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
shivendra singh
la source
-3

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

Antonio Ramasco
la source