Extraiga el nombre del archivo de la ruta, sin importar el formato del sistema operativo/ruta
¿Qué biblioteca de Python puedo usar para extraer nombres de archivos de rutas, sin importar cuál sea el sistema operativo o el formato de ruta?
Por ejemplo, me gustaría que todos estos caminos me devuelvan 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
14 answers
Usar os.path.split
o os.path.basename
como otros sugieren no funcionará en todos los casos: si está ejecutando el script en Linux e intenta procesar una ruta clásica al estilo de Windows, fallará.
Las rutas de Windows pueden usar una barra invertida o una barra diagonal como separador de rutas. Por lo tanto, el módulo ntpath
(que es equivalente a os.ruta de acceso cuando se ejecuta en Windows) funcionará para todos(1) caminos en todas las plataformas.
import ntpath
ntpath.basename("a/b/c")
Por supuesto, si el archivo termina con una barra, el nombre base estará vacío, así que haga su propia función para tratar con él:
def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)
Verificación:
>>> 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) Hay una advertencia: Los nombres de archivo de Linux pueden contener barras invertidas. Así que en linux, r'a/b\c'
siempre se refiere al archivo b\c
en la carpeta a
, mientras que en Windows, siempre se refiere al archivo c
en la subcarpeta b
de la carpeta a
. Por lo tanto, cuando se usan barras hacia adelante y hacia atrás en una ruta, necesita conocer la plataforma asociada para poder interprete correctamente. En la práctica, generalmente es seguro asumir que es una ruta de Windows, ya que las barras invertidas rara vez se usan en los nombres de archivo de Linux, pero tenga esto en cuenta cuando codifique para no crear agujeros de seguridad accidentales.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-28 21:12:59
En realidad, hay una función que devuelve exactamente lo que quieres
print(os.path.basename(your_path))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-17 15:43:17
Os.camino.split es la función que está buscando
head, tail = os.path.split("/tmp/d/a.dat")
>>> print(tail)
a.dat
>>> print(head)
/tmp/d
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-17 15:43:38
import os
head, tail = os.path.split(p)
print tail
Supongamos que p es la cadena de entrada, tail es lo que quieres.
Ver python os module docs para más detalles
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-05 11:45:21
En python 3
>>> from pathlib import Path
>>> Path("/tmp/d/a.dat").name
'a.dat'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-03 04:06:11
En su ejemplo también tendrá que quitar la barra diagonal de la derecha del lado derecho para volver c
:
>>> import os
>>> path = 'a/b/c/'
>>> path = path.rstrip(os.sep) # strip the slash from the right side
>>> os.path.basename(path)
'c'
Segundo nivel:
>>> os.path.filename(os.path.dirname(path))
'b'
Actualización: creo que lazyr
ha proporcionado la respuesta correcta. Mi código no funcionará con rutas similares a Windows en sistemas unix y vice versus con rutas similares a unix en el sistema windows.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-05 12:27:43
fname = str("C:\Windows\paint.exe").split('\\')[-1:][0]
Esto devolverá : pintura.exe
Cambie el valor sep de la función split con respecto a su ruta o sistema operativo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-03 07:39:49
Esto funciona para linux y Windows, así como con la biblioteca estándar
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]
Resultados:
['c', 'c', 'c', 'c', 'c', 'c', 'c']
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-18 15:39:19
Nunca he visto caminos de doble barra invertida, ¿existen? La característica incorporada del módulo python os
falla para ellos. Todos los demás trabajan, también la advertencia dada por usted con 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))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-19 21:18:33
El separador de Windows puede estar en un nombre de archivo Unix o en una ruta de Windows. El separador Unix solo puede existir en la ruta Unix. La presencia de un separador Unix indica una ruta que no es de Windows.
Lo siguiente separará (cortará el separador final) por el separador específico del sistema operativo, luego dividirá y devolverá el valor más a la derecha. Es feo, pero simple basado en la suposición anterior. Si la suposición es incorrecta, actualice y actualizaré esta respuesta para que coincida con la más precisa condición.
a.rstrip("\\\\" if a.count("/") == 0 else '/').split("\\\\" if a.count("/") == 0 else '/')[-1]
Código de ejemplo:
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])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-16 15:00:13
Tal vez solo mi solución todo en uno sin algo importante nuevo (considere el archivo temporal para crear archivos temporales :D )
import tempfile
abc = tempfile.NamedTemporaryFile(dir='/tmp/')
abc.name
abc.name.replace("/", " ").split()[-1]
Obtener los valores de abc.name
será una cadena como esta: '/tmp/tmpks5oksk7'
Así que puedo reemplazar el /
con un espacio .replace("/", " ")
y luego llamar split()
. Eso devolverá una lista y obtendré el
último elemento de la lista con [-1]
No es necesario importar ningún módulo.
Saludos cordiales
4k3nd0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-21 15:23:01
Aquí hay una solución regex, que parece funcionar con cualquier ruta del sistema operativo en cualquier sistema operativo.
No se necesita ningún otro módulo, y tampoco se necesita preprocesamiento:
import re
def extract_basename(path):
"""Extracts basename of a given path. Should Work with any OS Path on any OS"""
basename = re.search(r'[^\\/]+(?=[\\/]?$)', path)
if basename:
return basename.group(0)
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']
print([extract_basename(path) for path in paths])
# ['c', 'c', 'c', 'c', 'c', 'c', 'c']
extra_paths = ['C:\\', 'alone', '/a/space in filename', 'C:\\multi\nline']
print([extract_basename(path) for path in extra_paths])
# ['C:', 'alone', 'space in filename', 'multi\nline']
La expresión regular se puede probar aquí.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-17 15:44:10
Para completar, aquí está la solución pathlib
para python 3.2+:
>>> from pathlib import PureWindowsPath
>>> 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']
>>> [PureWindowsPath(path).name for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']
Esto funciona tanto en Windows como en Linux.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-24 14:31:00
filename = path[path.rfind('/')+1:]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-05 23:20:05