¿Cómo obtener el nombre de archivo sin la extensión de una ruta en Python?

1274

¿Cómo obtener el nombre de archivo sin la extensión de una ruta en Python?

Por ejemplo, si lo tuviera "/path/to/some/file.txt", querría "file".

1
  • 27
    Tuve que desplazarme bastante antes de encontrar la respuesta correcta clara para Python moderno: from pathlib import Path; print(Path("/path/to/some/file.txt").stem)>>>fileBallpointBen 31 de enero a las 4:39
1528

Obteniendo el nombre del archivo sin la extensión:

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

Huellas dactilares:

/path/to/some/file

Documentación paraos.path.splitext .

Nota importante: si el nombre del archivo tiene varios puntos, solo se elimina la extensión posterior a la última. Por ejemplo:

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

Huellas dactilares:

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

Vea otras respuestas a continuación si necesita manejar ese caso.

13
  • dieciséis
    Si esta es una operación bastante común, ¿quizás debería merecer su propio comando oficial? Algo como os.path.filename (path_to_file) en lugar de os.path.splitext (os.path.basename (path_to_file)) [0]Fnord 2 de julio de 2014 a las 17:13
  • 22
    ¿Qué pasa si el nombre del archivo contiene varios puntos? matteok 5/12/14 a las 17:42
  • 109
    Para cualquiera que se pregunte lo mismo que matteok, si hay varios puntos, splitext se divide en el último (por lo que splitext('kitty.jpg.zip')da ('kitty.jpg', '.zip')). Chuck 22/01/15 a las 18:15
  • 71
    Tenga en cuenta que este código devuelve la ruta completa del archivo (sin la extensión), no solo el nombre del archivo . Aran-Fey 17 oct 2018 a las 7:13
  • 14
    sí, entonces tendrías que hacer splitext(basename('/some/path/to/file.txt'))[0](lo que siempre parece estar haciendo)CpILL 4/11/19 a las 23:51
686

Puedes hacer el tuyo propio con:

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

Nota importante: si hay más de uno .en el nombre del archivo, solo se elimina el último. Por ejemplo:

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

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

Vea a continuación otras respuestas que abordan eso.

1
  • 9
    Esta respuesta debe tener la "marca verde"int soumen 5 de marzo a las 6:08
682

Usar .stemdesde pathliben Python 3.4+

from pathlib import Path

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

volverá

'file'

Tenga en cuenta que si su archivo tiene varias extensiones .stem, solo eliminará la última extensión. Por ejemplo, Path('file.tar.gz').stemvolverá 'file.tar'.

8
  • 42
    Esta es la forma recomendada desde python 3.Miladiouss 15 nov 2019 a las 2:21
  • 3
    Tenga en cuenta que, al igual que las os.pathsoluciones, esto solo eliminará una extensión (o suffix, como la pathlibllama). Path('a.b.c').stem == 'a.b'BallpointBen 18 de marzo de 2020 a las 4:26
  • 1
    @BallpointBen ¿cuál es la forma óptima de eliminar varios sufijos? Seguramente debe haber una manera mejor quePath(Path('a.b.c').stem).stem ... hoan 13 de mayo de 2020 a las 13:53
  • 6
    @hoan Creo que llamar repetidamente .with_suffix('')es el camino a seguir. Probablemente quieras recorrer hasta p.suffix == ''. BallpointBen 13 de mayo 20 y 15 h.
  • 3
    No funcionará para archivos con extensiones complejas: pathlib.Path('backup.tar.gz').stem-> 'backup.tarpero esperadobackuppymen 15/06/20 a las 11:11
250
>>> print(os.path.splitext(os.path.basename("/path/to/file/hemanth.txt"))[0])
hemanth
2
  • 7
    +1 para esto. 3 exactamente las mismas respuestas, pero esta es la más directa. Podría haberlo utilizado `para mostrar el código y "/somepath/hermanth.txt" como instancia de ruta. cregox 21 de mayo de 2010 a las 20:57
  • 2
    @ hemanth.hm Tenga en cuenta que en esta declaración que proporcionó, os.path.basenameno es necesario. os.path.basenamesolo debe usarse para obtener el nombre del archivo de la ruta del archivo. arrt_ 25 de enero de 2018 a las 12:53
104

En Python 3.4+ puedes usar la pathlibsolución

from pathlib import Path

print(Path(your_path).resolve().stem)
2
  • 6
    ¿Por qué sigues resolve()el camino? ¿Es realmente posible obtener una ruta a un archivo y que el nombre del archivo no forme parte de la ruta sin eso? Esto significa que si le da una ruta al enlace simbólico, devolverá el nombre del archivo (sin la extensión) del archivo al que apunta el enlace simbólico. Boris 11/10/19 a las 15:43
  • 1
    Una posible razón para usarlo resolve()es ayudar a lidiar con el problema de los puntos múltiples. La respuesta a continuación sobre el uso del índice no funcionará si la ruta es './foo.tar.gz'William Allcock 12 feb.20 a las 22:51
49

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

En python 3 pathlib "El módulo pathlib ofrece objetos de ruta de alto nivel". asi que,

>>> from pathlib import Path

>>> p = Path("/a/b/c.txt")
>>> p.with_suffix('')
WindowsPath('/a/b/c')
>>> p.stem
'c'
1
  • 5
    Esta es la mejor solución de Python 3 para el caso genérico de eliminar la extensión de una ruta completa. El uso de stem también elimina la ruta principal. En caso de que esté esperando una extensión doble (como bla.tar.gz), puede usarla dos veces: p.with_suffix (''). With_suffix (''). Eelco van Vliet 26/02/20 a las 12:37
30

os.path.splitext () no funcionará si hay varios puntos en la extensión.

Por ejemplo, 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

Puede encontrar el índice del primer punto en el nombre base y luego cortar el nombre base para obtener solo el nombre del archivo sin extensión.

>>> 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
4
  • 1
    index_of_dot = file_name.index ('.') Esto se hará después de obtener el nombre base del archivo para que no se divida en .envDheeraj Chakravarthi 5 de octubre de 2016 a las 4:22
  • 2
    Punto importante, ya que una serie de extensiones como esta es común. .tar.gz .tar.bz .tar.7zuser6798019 18/10/2017 a las 12:23
  • 3
    Tenga en cuenta que 'haystack'.index('needle')arroja una excepción ValueError si la aguja (en el caso anterior, el punto .) no se encuentra en el pajar. También existen archivos sin ninguna extensión. Czechnology 27/03/18 a las 7:54
  • para resolver ese problema, use un try-catch o use str.find()y verifique -1. si no hay un punto, regresafile_nameStarwarswii 15 de junio a las 17:52
29

Si desea mantener la ruta al archivo y simplemente eliminar la extensión

>>> file = '/root/dir/sub.exten/file.data.1.2.dat'
>>> print ('.').join(file.split('.')[:-1])
/root/dir/sub.exten/file.data.1.2
1
  • 20
    Si desea dividir en el último período, use rsplit:'/root/dir/sub.exten/file.data.1.2.dat'.rsplit('.', 1)IceArdor 4 dic 14 a las 22:32
24

@ IceAdor's se refiere a rsplit en un comentario a la solución de @ user2902201. rsplit es la solución más simple que admite múltiples períodos.

Aquí está escrito:

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

mi reporte

20

But even when I import os, I am not able to call it path.basename. Is it possible to call it as directly as basename?

import os, y luego usa os.path.basename

importing osno significa que pueda usar os.foosin consultar os.

3
  • 1
    aunque si quisieras llamar a foo directamente podrías usar from os import foo. tgray 24 mar 09 a las 17:33
  • tiene una versión muy no estándar del osmódulo si tiene un miembro llamado foo. Tadhg McDonald-Jensen 6 de junio de 2016 a las 21:13
  • 3
    Es un nombre de marcador de posición. (por ejemplo path, considere , o walk). Devin Jeanpierre 9/06/2016 a las 9:01
19

Pensé que agregaría una variación al uso de os.path.splitext sin la necesidad de usar la indexación de matrices.

La función siempre devuelve un (root, ext)par, por lo que es seguro de usar:

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

Ejemplo:

>>> import os
>>> path = 'my_text_file.txt'
>>> root, ext = os.path.splitext(path)
>>> root
'my_text_file'
>>> ext
'.txt'
1
  • os.path.splittext () es la versión 3.6+Yzmir Ramirez 2 abr.20 a las 2:04
15

Los otros métodos no eliminan varias extensiones. Algunos también tienen problemas con los nombres de archivo que no tienen extensiones. Este fragmento trata con ambas instancias y funciona tanto en Python 2 como en 3. Toma el nombre base de la ruta, divide el valor en puntos y devuelve el primero, que es la parte inicial del nombre del archivo.

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

Aquí hay un conjunto de ejemplos para ejecutar:

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

En todos los casos, el valor impreso es:

FileName
3
  • Excepto por el valor agregado de manejar múltiples puntos, este método es mucho más rápido que Path('/path/to/file.txt').stem. (1,23 μs frente a 8,39 μs)raratiru 6 de agosto de 2019 a las 18:02
  • Esto no funciona para el nombre de archivo nvdcve-1.1-2002.json.zipMichele 11/01/20 a las 19:46
  • Lo dividí en fileBasename.split ('. Json') [0] y funcionóMichele 11/01/20 a las 19:49
9

Dos o menos extensiones

Como se mencionó en los comentarios de otras respuestas de Pathlib, puede ser incómodo manejar múltiples sufijos. Dos o menos sufijos no es tan malo para manejar con .with_suffix('')y .stem.

from pathlib import Path

pth = Path('foo/bar/baz.baz/thefile.tar.gz')

fn = pth.with_suffix('').stem

print(fn)      # thefile

Cualquier cantidad de extensiones

Si puede haber más de dos extensiones, puede usar un bucle para manejar el caso general donde podría haber 0, 1 o muchos sufijos.

pth = Path('foo/bar/baz/thefile.tar.gz.bz.7zip')

pth.name       # 'thefile.tar.gz.bz.7zip'
pth.suffixes   # ['.tar', '.gz', '.bz', '.7zip']

asi que

fn = pth.name
for s in pth.suffixes:
    fn = fn.rsplit(s)[0]
    
print(fn)      # thefile

o

fnp = Path(pth.name)  
for _ in fnp.suffixes:
    fnp = fnp.with_suffix('')
    
print(fnp)     # thefile

Tenga en cuenta aquí que fnpes una ruta, mientras que fnes una cadena, lo que puede determinar la forma del bucle que se prefiere.

En el caso de que conozcas la primera extensión

Por ejemplo, si la extensión podría ser .tar, .tar.gz, .tar.gz.bz, etc; puede simplemente rsplitla extensión conocida y tomar el primer elemento:


pth = Path('foo/bar/baz.baz/thefile.tar.gz')

fn = pth.name.rsplit('.tar')[0]

print(fn)      # thefile
6

import os

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

Esto devuelve filenamesin el extension(C: \ Users \ Public \ Videos \ Sample Videos \ vida silvestre)

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

Ahora puede obtener solo el valor filenamede la temperatura con

os.path.basename(temp)   #this returns just the filename (wildlife)
0
6
import os
filename, file_extension =os.path.splitext(os.path.basename('/d1/d2/example.cs'))
  • nombre de archivo es 'ejemplo'

  • file_extension es '.cs'

'

1
  • esto en realidad responde a la pregunta del OPFred 30 de abril a las 12:14
5
import os
path = "a/b/c/abc.txt"
print os.path.splitext(os.path.basename(path))[0]
5

Un procedimiento con reconocimiento de múltiples extensiones. Obras para stry unicodecaminos. Funciona en Python 2 y 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)

Comportamiento:

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

Muy, muy, muy sencillo, sin otros módulos.

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

En el sistema Windows también utilicé el prefijo del nombre del controlador, como:

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

Entonces, como no necesito la letra de la unidad o el nombre del directorio, uso:

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

la forma más fácil de resolver esto es

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

esto le ahorra tiempo y costes de cálculo.

2

Podríamos hacer algo simple split/ popmágico como se ve aquí ( https://stackoverflow.com/a/424006/1250044 ), para extraer el nombre del archivo (respetando las diferencias de Windows y 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
3
  • os.path.splitext () [0] hace lo mismo. Charles Plager 13 de septiembre de 2016 a las 14:14
  • @CharlesPlager os.path.splitext () no funcionará si hay varios puntos en la extensión. stackoverflow.com/a/37760212/1250044yckart 13 de septiembre de 2016 a las 15:05
  • Me funciona: En [72]: os.path.splitext ('one.two.three.ext') Out [72]: ('one.two.three', '.ext')Charles Plager 13 de septiembre de 2016 a las 18:35
2

Para mayor comodidad, una función simple que envuelve los dos métodos 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

Probado con Python 3.5.

2

No busqué mucho, pero no vi a nadie que usara expresiones regulares para este problema.

Interpreté la pregunta como "dada una ruta, devuelva el nombre de base sin la extensión".

p.ej

"path/to/file.json" => "file"

"path/to/my.file.json" => "my.file"

En Python 2.7, donde todavía vivimos sin pathlib...

def get_file_name_prefix(file_path):
    basename = os.path.basename(file_path)

    file_name_prefix_match = re.compile(r"^(?P<file_name_pre fix>.*)\..*$").match(basename)

    if file_name_prefix_match is None:
        return file_name
    else:
        return file_name_prefix_match.group("file_name_prefix")
get_file_name_prefix("path/to/file.json")
>> file

get_file_name_prefix("path/to/my.file.json")
>> my.file

get_file_name_prefix("path/to/no_extension")
>> no_extension
2

Mejorando la respuesta de @spinup:

fn = pth.name
for s in pth.suffixes:
    fn = fn.rsplit(s)[0]
    break
    
print(fn)      # thefile 

Esto también funciona para nombres de archivo sin extensión.

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
0
1

He leído las respuestas y me doy cuenta de que hay muchas buenas soluciones. Entonces, para aquellos que buscan obtener (nombre o extensión), aquí va otra solución, usando el módulo os , ambos métodos admiten archivos con múltiples extensiones.

import os

def get_file_name(path):
    if not os.path.isdir(path):
        return os.path.splitext(os.path.basename(path))[0].split(".")[0]


def get_file_extension(path):
    extensions = []
    copy_path = path
    while True:
        copy_path, result = os.path.splitext(copy_path)
        if result != '':
            extensions.append(result)
        else:
            break
    extensions.reverse()
    return "".join(extensions)

Nota: esta solución en Windows no admite nombres de archivo con el carácter "\"