How do I get the filename without the extension from a path in Python?

PythonStringPath

Python Problem Overview


How do I get the filename without the extension from a path in Python?

"/path/to/some/file.txt""file"

Python Solutions


Solution 1 - Python

Getting the name of the file without the extension:

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

Prints:

/path/to/some/file

Documentation for os.path.splitext.

Important Note: If the filename has multiple dots, only the extension after the last one is removed. For example:

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

Prints:

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

See other answers below if you need to handle that case.

Solution 2 - Python

Use .stem from pathlib in Python 3.4+

from pathlib import Path

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

will return

'file'

Note that if your file has multiple extensions .stem will only remove the last extension. For example, Path('file.tar.gz').stem will return 'file.tar'.

Solution 3 - Python

You can make your own with:

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

Important note: If there is more than one . in the filename, only the last one is removed. For example:

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

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

See below for other answers that address that.

Solution 4 - Python

>>> print(os.path.splitext(os.path.basename("/path/to/file/hemanth.txt"))[0])
hemanth

Solution 5 - Python

In Python 3.4+ you can use the pathlib solution

from pathlib import Path

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

Solution 6 - Python

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

In python 3 pathlib "The pathlib module offers high-level path objects." so,

>>> from pathlib import Path

>>> p = Path("/a/b/c.txt")
>>> p.with_suffix('')
WindowsPath('/a/b/c')
>>> p.stem
'c'

Solution 7 - Python

os.path.splitext() won't work if there are multiple dots in the extension.

For example, 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

You can just find the index of the first dot in the basename and then slice the basename to get just the filename without 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

Solution 8 - Python

If you want to keep the path to the file and just remove the extension

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

Solution 9 - Python

As noted by @IceAdor in a comment to @user2902201's solution, rsplit is the simplest solution robust to multiple periods (by limiting the number of splits to maxsplit of just 1 (from the end of the string)).

Here it is spelt out:

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

my.report

Solution 10 - Python

Thought I would throw in a variation to the use of the os.path.splitext without the need to use array indexing.

The function always returns a (root, ext) pair so it is safe to use:

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

Example:

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

Solution 11 - Python

> 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, and then use os.path.basename

importing os doesn't mean you can use os.foo without referring to os.

Solution 12 - Python

import os
filename, file_extension =os.path.splitext(os.path.basename('/d1/d2/example.cs'))
  • filename is 'example'

  • file_extension is '.cs'

'

Solution 13 - Python

The other methods don't remove multiple extensions. Some also have problems with filenames that don't have extensions. This snippet deals with both instances and works in both Python 2 and 3. It grabs the basename from the path, splits the value on dots, and returns the first one which is the initial part of the filename.

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

Here's a set of examples to run:

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

In every case, the value printed is:

FileName

Solution 14 - Python

Answers using Pathlib for Several Scenarios

Using Pathlib, it is trivial to get the filename when there is just one extension (or none), but it can be awkward to handle the general case of multiple extensions.

Zero or One extension
from pathlib import Path

pth = Path('./thefile.tar')

fn = pth.stem

print(fn)      # thefile


# Explanation:
# the `stem` attribute returns only the base filename, stripping
# any leading path if present, and strips the extension after
# the last `.`, if present.


# Further tests

eg_paths = ['thefile',
            'thefile.tar',
            './thefile',
            './thefile.tar',
            '../../thefile.tar',
            '.././thefile.tar',
            'rel/pa.th/to/thefile',
            '/abs/path/to/thefile.tar']

for p in eg_paths:
    print(Path(p).stem)  # prints thefile every time
Two or fewer extensions
from pathlib import Path

pth = Path('./thefile.tar.gz')

fn = pth.with_suffix('').stem

print(fn)      # thefile


# Explanation:
# Using the `.with_suffix('')` trick returns a Path object after
# stripping one extension, and then we can simply use `.stem`.


# Further tests

eg_paths += ['./thefile.tar.gz',
             '/abs/pa.th/to/thefile.tar.gz']

for p in eg_paths:
    print(Path(p).with_suffix('').stem)  # prints thefile every time
Any number of extensions (0, 1, or more)
from pathlib import Path

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

fn = pth.name
if len(pth.suffixes) > 0:
    s = pth.suffixes[0]
    fn = fn.rsplit(s)[0]

# or, equivalently

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

# or simply run the full loop

fn = pth.name
for _ in pth.suffixes:
    fn = fn.rsplit('.')[0]

# In any case:

print(fn)     # thefile


# Explanation
#
# pth.name     -> 'thefile.tar.gz.bz.7zip'
# pth.suffixes -> ['.tar', '.gz', '.bz', '.7zip']
#
# If there may be more than two extensions, we can test for
# that case with an if statement, or simply attempt the loop
# and break after rsplitting on the first extension instance.
# Alternatively, we may even run the full loop and strip one 
# extension with every pass.


# Further tests

eg_paths += ['./thefile.tar.gz.bz.7zip',
             '/abs/pa.th/to/thefile.tar.gz.bz.7zip']

for p in eg_paths:
    pth = Path(p)
    fn = pth.name
    for s in pth.suffixes:
        fn = fn.rsplit(s)[0]
        break

    print(fn)  # prints thefile every time
Special case in which the first extension is known

For instance, if the extension could be .tar, .tar.gz, .tar.gz.bz, etc; you can simply rsplit the known extension and take the first element:


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

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

print(fn)      # thefile

Solution 15 - Python

import os

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

This returns the filename without the extension(C:\Users\Public\Videos\Sample Videos\wildlife)

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

Now you can get just the filename from the temp with

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

Solution 16 - Python

A multiple extension aware procedure. Works for str and unicode paths. Works in Python 2 and 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)

Behavior:

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

Solution 17 - Python

Very very very simpely no other modules !!!

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)

Solution 18 - Python

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

Solution 19 - Python

On Windows system I used drivername prefix as well, like:

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

So because I do not need drive letter or directory name, I use:

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

Solution 20 - Python

Improving upon @spinup answer:

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

This works for filenames without extension also

Solution 21 - Python

I've read the answers, and I notice that there are many good solutions. So, for those who are looking to get either (name or extension), here goes another solution, using the os module, both methods support files with multiple extensions.

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)

Note: this solution on windows does not support file names with the "\" character

Solution 22 - Python

We could do some simple split / pop magic as seen here (https://stackoverflow.com/a/424006/1250044), to extract the filename (respecting the windows and POSIX differences).

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

Solution 23 - Python

For convenience, a simple function wrapping the two methods from 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

Tested with Python 3.5.

Solution 24 - Python

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

Solution 25 - Python

the easiest way to resolve this is to

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

this saves you time and computation cost.

Solution 26 - Python

I didn't look very hard but I didn't see anyone who used regex for this problem.

I interpreted the question as "given a path, return the basename without the extension."

e.g.

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

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

In Python 2.7, where we still live without 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

Solution 27 - Python

What about the following?

import pathlib
filename = '/path/to/dir/stem.ext.tar.gz'
pathlib.Path(filename).name[:-len(''.join(pathlib.Path(filename).suffixes))]
# -> 'stem'

or this equivalent?

pathlib.Path(filename).name[:-sum(map(len, pathlib.Path(filename).suffixes))]

Solution 28 - Python

# use pathlib. the below works with compound filetypes and normal ones
source_file = 'spaces.tar.gz.zip.rar.7z'
source_path = pathlib.Path(source_file)
source_path.name.replace(''.join(source_path.suffixes), '')
>>> 'spaces'

despite the many working implementations described above I added this ^ as it uses pathlib only and works for compound filetypes and normal ones

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJoan VengeView Question on Stackoverflow
Solution 1 - PythonGeoView Answer on Stackoverflow
Solution 2 - PythonmxdbldView Answer on Stackoverflow
Solution 3 - PythongimelView Answer on Stackoverflow
Solution 4 - Pythonhemanth.hmView Answer on Stackoverflow
Solution 5 - PythonMorgothView Answer on Stackoverflow
Solution 6 - PythonjjisnowView Answer on Stackoverflow
Solution 7 - PythonDheeraj ChakravarthiView Answer on Stackoverflow
Solution 8 - Pythonuser2902201View Answer on Stackoverflow
Solution 9 - PythondlinkView Answer on Stackoverflow
Solution 10 - PythonScottMcCView Answer on Stackoverflow
Solution 11 - PythonDevin JeanpierreView Answer on Stackoverflow
Solution 12 - PythonAntonio RamascoView Answer on Stackoverflow
Solution 13 - PythonAlan W. SmithView Answer on Stackoverflow
Solution 14 - PythonspinupView Answer on Stackoverflow
Solution 15 - PythonlearncodeView Answer on Stackoverflow
Solution 16 - Pythonuser6798019View Answer on Stackoverflow
Solution 17 - PythonBilalView Answer on Stackoverflow
Solution 18 - Pythonuser4949344View Answer on Stackoverflow
Solution 19 - PythonZéikszView Answer on Stackoverflow
Solution 20 - PythonM GaneshView Answer on Stackoverflow
Solution 21 - Pythonesteban21View Answer on Stackoverflow
Solution 22 - PythonyckartView Answer on Stackoverflow
Solution 23 - PythonhandleView Answer on Stackoverflow
Solution 24 - Pythonshivendra singhView Answer on Stackoverflow
Solution 25 - PythonNkoro Joseph AhamefulaView Answer on Stackoverflow
Solution 26 - PythonJohn CarrellView Answer on Stackoverflow
Solution 27 - PythonwolfrevoView Answer on Stackoverflow
Solution 28 - PythonJohn---View Answer on Stackoverflow