stephan
stephan

Reputation: 2393

How to delete a file by extension in Python?

I was messing around just trying to make a script that deletes items by ".zip" extension.

import sys
import os
from os import listdir

test=os.listdir("/Users/ben/downloads/")

for item in test:
    if item.endswith(".zip"):
        os.remove(item)

Whenever I run the script I get:

OSError: [Errno 2] No such file or directory: 'cities1000.zip'

cities1000.zip is obviously a file in my downloads folder.

What did I do wrong here? Is the issue that os.remove requires the full path to the file? If this is the issue, than how can I do that in this current script without completely rewriting it.

Upvotes: 56

Views: 106238

Answers (7)

Serdalis
Serdalis

Reputation: 10489

For this operation you need to append the file name on to the file path so the command knows what folder you are looking into.

You can do this correctly and in a portable way in python using the os.path.join command.
For example:

import os

directory = "/Users/ben/downloads/"
test = os.listdir( directory )

for item in test:
    if item.endswith(".zip"):
        os.remove( os.path.join( directory, item ) )

Upvotes: 13

Paulden
Paulden

Reputation: 51

I think you could use Pathlib-- a modern way, like the following:

import pathlib


dir = pathlib.Path("/Users/ben/downloads/")
zip_files = dir.glob(dir / "*.zip")
for zf in zip_files:
    zf.unlink()

If you want to delete all zip files recursively, just write so:

import pathlib


dir = pathlib.Path("/Users/ben/downloads/")
zip_files = dir.rglob(dir / "*.zip")  # recursively
for zf in zip_files:
    zf.unlink()

Upvotes: 5

Rafael de Bem
Rafael de Bem

Reputation: 828

Just leaving my two cents on this issue: if you want to be chic you can use glob or iglob from the glob package, like so:

import glob
import os

files_in_dir = glob.glob('/Users/ben/downloads/*.zip')
# or if you want to be fancy, you can use iglob, which returns an iterator:
files_in_dir = glob.iglob('/Users/ben/downloads/*.zip')

for _file in files_in_dir:
    print(_file) # just to be sure, you know how it is...
    os.remove(_file)

Upvotes: 3

idjaw
idjaw

Reputation: 26560

You can set the path in to a dir_name variable, then use os.path.join for your os.remove.

import os

dir_name = "/Users/ben/downloads/"
test = os.listdir(dir_name)

for item in test:
    if item.endswith(".zip"):
        os.remove(os.path.join(dir_name, item))

Upvotes: 100

ShadowRanger
ShadowRanger

Reputation: 155323

Alternate approach that avoids join-ing yourself over and over: Use glob module to join once, then let it give you back the paths directly.

import glob
import os

dir = "/Users/ben/downloads/"

for zippath in glob.iglob(os.path.join(dir, '*.zip')):
    os.remove(zippath)

Upvotes: 11

johncruise
johncruise

Reputation: 26

origfolder = "/Users/ben/downloads/"
test = os.listdir(origfolder)

for item in test:
    if item.endswith(".zip"):
        os.remove(os.path.join(origfolder, item))

The dirname is not included in the os.listdir output. You have to attach it to reference the file from the list returned by said function.

Upvotes: 1

David
David

Reputation: 46

Prepend the directory to the filename

os.remove("/Users/ben/downloads/" + item)

EDIT: or change the current working directory using os.chdir.

Upvotes: 0

Related Questions