135

Is there a way I can use glob on a directory, to get files with a specific extension, but only the filename itself, not the whole path?

10 Answers10

200

Use os.path.basename(path) to get the filename.

Leland Hepworth
  • 876
  • 9
  • 16
Tom Zych
  • 13,329
  • 9
  • 36
  • 53
  • This is not exactly the same as relative glob though. Imagine the pattern is `"sql/*.sql"`. The `os.listdir` function would actually list file paths relative to the given directory, though it does not work with patterns. EDIT: Ah, I was looking for this answer: https://stackoverflow.com/a/44994860/1317713 The trick is using `os.path.relpath` rather than `basename`. – Leonid Oct 15 '21 at 03:44
  • thanks for the answer. How to get rid the extension part..such as .csv, .dat, .nc, etc – Azam Dec 31 '22 at 05:14
181

This might help someone:

names = [os.path.basename(x) for x in glob.glob('/your_path')]

Anastasios Andronidis
  • 6,310
  • 4
  • 30
  • 53
  • Alternatively they would use [os.path.relpath](https://docs.python.org/3/library/os.path.html#os.path.relpath) instead of [os.path.basename](https://docs.python.org/3/library/os.path.html#os.path.basename) if they want a relative path to `'/your_path'` rather than just the filename. – Leonid Oct 15 '21 at 03:53
  • relpath or just `old = os.getcwd(); os.chdir(dir); files = glob.glob('**/*.txt'); os.chdir(old)` – milahu Jul 06 '22 at 10:26
19
map(os.path.basename, glob.glob("your/path"))

Returns an iterable with all the file names and extensions.

Víctor Navarro
  • 812
  • 9
  • 12
5

os.path.basename works for me.

Here is Code example:

import sys,glob
import os

expectedDir = sys.argv[1]                                                    ## User input for directory where files to search

for fileName_relative in glob.glob(expectedDir+"**/*.txt",recursive=True):       ## first get full file name with directores using for loop

    print("Full file name with directories: ", fileName_relative)

    fileName_absolute = os.path.basename(fileName_relative)                 ## Now get the file name with os.path.basename

    print("Only file name: ", fileName_absolute)

Output :

Full file name with directories:  C:\Users\erinksh\PycharmProjects\EMM_Test2\venv\Lib\site-packages\wheel-0.33.6.dist-info\top_level.txt
Only file name:  top_level.txt
rinkush sharda
  • 351
  • 3
  • 3
  • You have mixed up your variable names: absolute means full path; relative means only the base name. – omatai Apr 29 '20 at 23:01
3

I keep rewriting the solution for relative globbing (esp. when I need to add items to a zipfile) - this is what it usually ends up looking like.

# Function
def rel_glob(pattern, rel):
    """glob.glob but with relative path
    """
    for v in glob.glob(os.path.join(rel, pattern)):
        yield v[len(rel):].lstrip("/")

# Use
# For example, when you have files like: 'dir1/dir2/*.py'
for p in rel_glob("dir2/*.py", "dir1"):
    # do work
    pass
turtlemonvh
  • 9,149
  • 6
  • 47
  • 53
2

If you are looking for CSV file:

file = [os.path.basename(x) for x in glob.glob(r'C:\Users\rajat.prakash\Downloads//' + '*.csv')]

If you are looking for EXCEL file:

file = [os.path.basename(x) for x in glob.glob(r'C:\Users\rajat.prakash\Downloads//' + '*.xlsx')]
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
rajat prakash
  • 189
  • 1
  • 6
2

None of the existing answers mention using the new pathlib module, which is what I was searching for, so I'll add a new answer here.

Path.glob produces Path objects containing the full path including any directories. If you only need the file names, use the Path.name property.


If you find yourself frequently converting between pathlib and os.path, check out this handy table converting functions between the two libraries.

Leland Hepworth
  • 876
  • 9
  • 16
1
for f in glob.glob(gt_path + "/*.png"):  # find all png files
      exc_name = f.split('/')[-1].split(',')[0]

Then the exc_name is like myphoto.png

Nice
  • 97
  • 1
  • 6
1

Or using pathlib:

from pathlib import Path

dir_URL = Path("your_directory_URL") # e.g. Path("/tmp")
filename_list = [file.name for file in dir_URL.glob("your_pattern")]
burn4science
  • 61
  • 2
  • 4
1

Use glob.glob("*.filetype") to get a list of all files with complete path and use os.path.basename(list_item) to remove the extra path and retain only the filename.

Here is an example:

import glob
a=glob.glob("*.pkl")

It returns a list with the complete path of each file ending with .pkl

Now you can remove the path information and extract only the filename for an list item using:

import os
b=os.path.basename(a[0]) 
# This is an example to extract filename for only one list item

If you need to create an entire list with only the filename:

bb=[os.path.basename(list_item) for list_item in a]
Binod
  • 397
  • 4
  • 5