Question Extraire le nom du fichier du chemin, quel que soit le format de l'os / chemin


Quelle bibliothèque Python puis-je utiliser pour extraire les noms de fichiers à partir de chemins, quel que soit le système d'exploitation ou le format de chemin d'accès?

Par exemple, j'aimerais que tous ces chemins me retournent c:

a/b/c/
a/b/c
\a\b\c
\a\b\c\
a\b\c
a/b/../../a/b/c/
a/b/../../a/b/c

430
2017-12-05 11:39


origine


Réponses:


En utilisant os.path.split ou os.path.basename comme le suggèrent d'autres ne fonctionnera pas dans tous les cas: si vous exécutez le script sous Linux et essayez de traiter un chemin de style Windows classique, il échouera.

Les chemins Windows peuvent utiliser une barre oblique inverse ou une barre oblique comme séparateur de chemin. Par conséquent, la ntpath module (qui est équivalent à os.path lors de l'exécution sur Windows) fonctionnera pour tous(1) chemins sur toutes les plates-formes.

import ntpath
ntpath.basename("a/b/c")

Bien sûr, si le fichier se termine par une barre oblique, le nom de base sera vide, alors faites votre propre fonction pour y faire face:

def path_leaf(path):
    head, tail = ntpath.split(path)
    return tail or ntpath.basename(head)

Vérification:

>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', 
...     'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']


(1) Il y a une mise en garde: les noms de fichiers Linux peut contenir des barres obliques inverses. Donc sur Linux, r'a/b\c' se réfère toujours au fichier b\c dans le a dossier, sous Windows, il se réfère toujours à c déposer dans le b sous-dossier du a dossier. Donc, lorsque les barres obliques avant et arrière sont utilisées dans un chemin, vous avoir besoin connaître la plateforme associée pour pouvoir l'interpréter correctement. En pratique, il est généralement prudent de supposer qu'il s'agit d'un chemin d'accès Windows puisque les barres obliques inverses sont rarement utilisées dans les noms de fichiers Linux, mais gardez cela à l'esprit lorsque vous codez afin de ne pas créer de failles de sécurité accidentelles.


483
2017-12-05 11:45



En fait, il y a un fonction qui retourne exactement ce que vous voulez

print(os.path.basename(your_path))

692
2017-12-05 11:49



os.path.split est la fonction que vous recherchez

head, tail = os.path.split("/tmp/d/a.dat")

>>> print(tail)
a.dat
>>> print(head)
/tmp/d

131
2017-12-05 11:45



import os
head, tail = os.path.split(p)
print tail

Supposons que p soit la chaîne d'entrée, tail est ce que vous voulez.

Voir python os module docs pour le détail


28
2017-12-05 11:45



Dans votre exemple, vous devrez également supprimer la barre oblique de droite à droite c:

>>> import os
>>> path = 'a/b/c/'
>>> path = path.rstrip(os.sep) # strip the slash from the right side
>>> os.path.basename(path)
'c'

Deuxième niveau:

>>> os.path.filename(os.path.dirname(path))
'b'

mise à jour: je pense lazyr a fourni la bonne réponse. Mon code ne fonctionnera pas avec les chemins de type Windows sur les systèmes Unix et vice contre les chemins de type Unix sur le système Windows.


9
2017-12-05 11:51



En python 3

>>> from pathlib import Path    
>>> Path("/tmp/d/a.dat").name
'a.dat'

7
2018-02-03 04:06



fname = str("C:\Windows\paint.exe").split('\\')[-1:][0]

cela reviendra: paint.exe

changez la valeur sépare de la fonction split en fonction de votre chemin ou de votre système d'exploitation.


6
2017-11-03 07:39



Cela fonctionne pour linux et windows aussi bien avec la bibliothèque standard

paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
         'a/b/../../a/b/c/', 'a/b/../../a/b/c']

def path_leaf(path):
    return path.strip('/').strip('\\').split('/')[-1].split('\\')[-1]

[path_leaf(path) for path in paths]

Résultats:

['c', 'c', 'c', 'c', 'c', 'c', 'c']

6
2018-06-18 15:39



Je n'ai jamais vu de chemins de double-backslashed, existent-ils? La fonctionnalité intégrée du module python os échoue pour ceux. Tous les autres travaux, aussi la mise en garde donnée par vous avec os.path.normpath():

paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', 
...     'a/b/../../a/b/c/', 'a/b/../../a/b/c', 'a/./b/c', 'a\b/c']
for path in paths:
    os.path.basename(os.path.normpath(path))

4
2018-03-19 21:18



Le séparateur Windows peut être dans un nom de fichier Unix ou un chemin d'accès Windows. Le séparateur Unix ne peut exister que dans le chemin Unix. La présence d'un séparateur Unix indique un chemin non Windows.

Ce qui suit va supprimer (couper séparateur) par le séparateur spécifique OS, puis diviser et retourner la valeur la plus à droite. C'est moche, mais simple basé sur l'hypothèse ci-dessus. Si l'hypothèse est incorrecte, veuillez mettre à jour et je mettrai à jour cette réponse pour qu'elle corresponde aux conditions les plus précises.

a.rstrip("\\\\" if a.count("/") == 0 else '/').split("\\\\" if a.count("/") == 0 else '/')[-1]

exemple de code:

b = ['a/b/c/','a/b/c','\\a\\b\\c','\\a\\b\\c\\','a\\b\\c','a/b/../../a/b/c/','a/b/../../a/b/c']

for a in b:

    print (a, a.rstrip("\\" if a.count("/") == 0 else '/').split("\\" if a.count("/") == 0 else '/')[-1])

3
2018-05-16 14:29



Peut-être juste ma solution tout-en-un sans importance quelque chose de nouveau (compte tenu du tempfile pour créer des fichiers temporaires: D)

import tempfile
abc = tempfile.NamedTemporaryFile(dir='/tmp/')
abc.name
abc.name.replace("/", " ").split()[-1] 

Obtenir les valeurs de abc.name sera une chaîne comme ceci: '/tmp/tmpks5oksk7' Je peux donc remplacer le / avec un espace .replace("/", " ") puis appelez split(). Cela va retourner une liste et je reçois le dernier élément de la liste avec [-1]

Pas besoin d'importer un module.

meilleures salutations

4k3nd0


2
2017-08-21 15:23