user1681573
user1681573

Reputation: 933

Python, Deleting all files in a folder older than X days

I'm trying to write a python script to delete all files in a folder older than X days. This is what I have so far:

import os, time, sys
    
path = r"c:\users\%myusername%\downloads"
now = time.time()

for f in os.listdir(path):
  if os.stat(f).st_mtime < now - 7 * 86400:
    if os.path.isfile(f):
      os.remove(os.path.join(path, f))

When I run the script, I get:

Error2 - system cannot find the file specified,

and it gives the filename. What am I doing wrong?

Upvotes: 85

Views: 151490

Answers (14)

Jos&#233; Iba&#241;ez
Jos&#233; Iba&#241;ez

Reputation: 712

This is my code, cleanup old files and empty folders, and recursive:

import os
import time
from pathlib import Path

def cleanup_old_files(localRepo=LOCAL_PATH,age=60):

    critical_time = time.time() - age * 24 * 3600

    for item in Path(localRepo).expanduser().rglob('*'):
        if item.is_file():
            if os.stat(item).st_mtime < critical_time:
                os.remove(item)

    for item in Path(localRepo).expanduser().rglob('*'):    
        if item.is_dir():
            if len(os.listdir(item)) == 0:
                os.rmdir(item)

Upvotes: 0

Owais Ajaz
Owais Ajaz

Reputation: 264

just give the path directory and list down the files within it

destination_path = './level1/level2/path'
# delete archieve file older than 2 days
current_day = time.time()
for filename in os.listdir(destination_path):
   if os.path.getmtime(os.path.join(destination_path, filename)) < current_day - 1 * 86400:
      if os.path.isfile(os.path.join(destination_path, filename)):
         os.remove(os.path.join(destination_path, filename))

Upvotes: 0

Bill Bell
Bill Bell

Reputation: 21643

I think the new pathlib thingy together with the arrow module for dates make for neater code.

from pathlib import Path
import arrow

files_path = r"C:\scratch\removeThem"

critical_time = arrow.now().shift(hours=+5).shift(days=-7)

for item in Path(files_path).glob('*'):
    if item.is_file():
        print(str(item.absolute()))
        item_time = arrow.get(item.stat().st_mtime)
        if item_time < critical_time :
            # remove it
            pass
  • pathlib makes it easy to list the directory contents, to access file characteristics such as as creation times and to get full paths.
  • arrow makes calculations of times easier and neater.

Here's the output showing the full paths offered by pathlib. (No need to join.)

C:\scratch\removeThem\four.txt
C:\scratch\removeThem\one.txt
C:\scratch\removeThem\three.txt
C:\scratch\removeThem\two.txt

Upvotes: 25

Mansur Ul Hasan
Mansur Ul Hasan

Reputation: 3606

i did it in more sufficient way

import os, time

path = "/home/mansoor/Documents/clients/AirFinder/vendors"
now = time.time()

for filename in os.listdir(path):
    filestamp = os.stat(os.path.join(path, filename)).st_mtime
    seven_days_ago = now - 7 * 86400
    if filestamp < seven_days_ago:
        print(filename)

Upvotes: 13

fracat
fracat

Reputation: 11

I might be a tad late to the party but this is my approach using pathlib's timestamp to convert date object to a float and compare it to file.stat().st_mtime

from pathlib import Path
import datetime as dt
from time import ctime


remove_before = dt.datetime.now()-dt.timedelta(days=10) files older than 10 days

removeMe = Path.home() / 'downloads' # points to :\users\%myusername%\
for file in removeMe.iterdir(): 
    if remove_before.timestamp() > file.stat().st_mtime:
        print(ctime(file.stat().st_mtime)) 
        file.unlink() # to delete the file

Upvotes: 1

manu bharadwaj
manu bharadwaj

Reputation: 29

Some of the other answers also have the same code but i feel they have overcomplicated a very simple process

import os
import time

#folder to clear from
dir_path = 'path of directory to clean'
#No of days before which the files are to be deleted
limit_days = 10

treshold = time.time() - limit_days*86400
entries = os.listdir(dir_path)
for dir in entries:
    creation_time = os.stat(os.path.join(dir_path,dir)).st_ctime
    if creation_time < treshold:
        print(f"{dir} is created on {time.ctime(creation_time)} and will be deleted")

Upvotes: 1

gabeyww
gabeyww

Reputation: 39

Here's how I do it on my Windows machines. It uses shutil to also remove subdirectories created in downloads. I also have a similar one to keep the folders cleaned up on the hard drive of my son's computer, as he has special needs and tends to let things get out of control fast.

import os, time, shutil

paths = (("C:"+os.getenv('HOMEPATH')+"\Downloads"), (os.getenv('TEMP')))
oneday = (time.time())- 1 * 86400

try:
    for path in paths:
        for filename in os.listdir(path):
            if os.path.getmtime(os.path.join(path, filename)) < oneday:
                if os.path.isfile(os.path.join(path, filename)):
                    print(filename)
                    os.remove(os.path.join(path, filename))
                elif os.path.isdir(os.path.join(path, filename)):
                    print(filename)
                    shutil.rmtree((os.path.join(path, filename)))
                    os.remove(os.path.join(path, filename))
except:
    pass
                
print("Maintenance Complete!")

Upvotes: 1

britodfbr
britodfbr

Reputation: 1991

With comprehensions, Can be:

import os
from time import time


p='.'
result=[os.remove(file) for file in (os.path.join(path, file) for path, _, files in os.walk(p) for file in files) if os.stat(file).st_mtime < time() - 7 * 86400]
print(result)
  • remove files with match = os.remove(file)
  • loop for all files into path = for file in
  • generation with all files = (os.path.join(path, file) for path, _, files in os.walk(p) for file in files)
  • p is a directory into filesystem
  • verify mtime to match= if os.stat(file).st_mtime < time() - 7 * 86400

May be see: https://ideone.com/Bryj1l

Upvotes: 1

user9652688
user9652688

Reputation:

You need to use if os.stat(os.path.join(path, f)).st_mtime < now - 7 * 86400: instead of if os.stat(f).st_mtime < now - 7 * 86400:

I find using os.path.getmtime more convenient :-

import os, time

path = r"c:\users\%myusername%\downloads"
now = time.time()

for filename in os.listdir(path):
    # if os.stat(os.path.join(path, filename)).st_mtime < now - 7 * 86400:
    if os.path.getmtime(os.path.join(path, filename)) < now - 7 * 86400:
        if os.path.isfile(os.path.join(path, filename)):
            print(filename)
            os.remove(os.path.join(path, filename))

Upvotes: 10

santosh
santosh

Reputation: 105

This deletes files older than 60 days.

import os

directory = '/home/coffee/Documents'

os.system("find " + directory + " -mtime +60 -print")
os.system("find " + directory + " -mtime +60 -delete")

Upvotes: 3

Cory Ronquist
Cory Ronquist

Reputation: 1

would like to add what i came up with to do this task. the function is called in the login process.

    def remove_files():
        removed=0
        path = "desired path"
        # Check current working directory.
        dir_to_search = os.getcwd()
        print "Current working directory %s" % dir_to_search
        #compare current to desired directory
        if dir_to_search != "full desired path":
            # Now change the directory
            os.chdir( desired path )
            # Check current working directory.
            dir_to_search = os.getcwd()
            print "Directory changed successfully %s" % dir_to_search
        for dirpath, dirnames, filenames in os.walk(dir_to_search):
           for file in filenames:
              curpath = os.path.join(dirpath, file)
              file_modified = datetime.datetime.fromtimestamp(os.path.getmtime(curpath))
              if datetime.datetime.now() - file_modified > datetime.timedelta(hours=1):
                  os.remove(curpath)
                  removed+=1
        print(removed)

Upvotes: 0

Xman Classical
Xman Classical

Reputation: 5406

A simple python script to remove /logs/ files older than 10 days

#!/usr/bin/python

# run by crontab
# removes any files in /logs/ older than 10 days

import os, sys, time
from subprocess import call

def get_file_directory(file):
    return os.path.dirname(os.path.abspath(file))

now = time.time()
cutoff = now - (10 * 86400)

files = os.listdir(os.path.join(get_file_directory(__file__), "logs"))
file_path = os.path.join(get_file_directory(__file__), "logs/")
for xfile in files:
    if os.path.isfile(str(file_path) + xfile):
        t = os.stat(str(file_path) + xfile)
        c = t.st_ctime

        # delete file if older than 10 days
        if c < cutoff:
            os.remove(str(file_path) + xfile)

With __file__ you can replace by your path.

Upvotes: 4

kindall
kindall

Reputation: 184171

os.listdir() returns a list of bare filenames. These do not have a full path, so you need to combine it with the path of the containing directory. You are doing this when you go to delete the file, but not when you stat the file (or when you do isfile() either).

Easiest solution is just to do it once at the top of your loop:

f = os.path.join(path, f)

Now f is the full path to the file and you just use f everywhere (change your remove() call to just use f too).

Upvotes: 38

Joran Beasley
Joran Beasley

Reputation: 113978

You need to give it the path also or it will look in cwd.. which ironically enough you did on the os.remove but no where else...

for f in os.listdir(path):
    if os.stat(os.path.join(path,f)).st_mtime < now - 7 * 86400:

Upvotes: 16

Related Questions