staging.inyokaproject.org

mit Python dateien löschen die älter sind als x

Status: Ungelöst | Ubuntu-Version: Xubuntu 16.04 (Xenial Xerus)
Antworten |

matze31

Anmeldungsdatum:
25. Oktober 2015

Beiträge: 795

Hallo, ich bin noch recht Anfänger in Python, und möchte ein Script erstellen, was Dateien löscht die älter sind als x Tage. Mein Ziel ist es in einen Verzeichnis Die Dateien zu löschen, die älter als z.B. 10 Tage sind. Jetzt hab ich angefangen und ein Probe Verzeichnis Namens pyprobe und die Datei 1 erstellt. So sieht mein bisheriges Python Script aus, was aber hinten und vorne nicht stimmen kann, denn die Datei wird immer gelöscht. Ich möchte auch das Script so klein wie möglich halten.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import datetime
import os
import time
import sys


a= '/home/matze/pyprobe/1'
now = time.time()

  
if a > now - 1 *  60:
       os.remove(a)

Die Datei sollte gelöscht werden, wenn sie älter als 60 sekunden ist, aber sie lässt sich immer löschen, auch wenn die Datei nur 30 Sekunden alt ist. Kann mir jemand helfen?

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Du fragst ja nirgends das Datei-Datum ab, wie soll er dann wissen, wie alt die Datei ist ?

Ich kenne mich zwar selbst kaum mit Python aus, aber dieser Artikel auf Stack Exchange befasst sich mit dem Thema.

LG,

track

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

matze31 schrieb:

So sieht mein bisheriges Python Script aus, was aber hinten und vorne nicht stimmen kann, denn die Datei wird immer gelöscht.

Du vergleichst einen string mit einem float (Schau dir die Dokumentation zu time.time() an), was in Python2 dummerweise funktioniert (vgl. https://stackoverflow.com/a/19713563), in Python3 fliegt dir das direkt um die Ohren.

Ich möchte auch das Script so klein wie möglich halten.

Wichtig ist erst mal, dass der Code korrekt funktioniert, optimieren kann man es danach immer noch.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/usr/bin/env python3
import os
from datetime import datetime, timedelta

file_path='/tmp/foo'
file_mtime = datetime.fromtimestamp(os.path.getmtime(file_path))
max_mtime = datetime.now() - timedelta(seconds=60)

if file_mtime < max_mtime:
    os.remove(file_path)

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Willst Du mehr Dateien löschen oder mehr Python lernen?

1
find -mtime +10 -delete 

(ungeprüft, löscht auch in Unterverzeichnisssen)

matze31

(Themenstarter)

Anmeldungsdatum:
25. Oktober 2015

Beiträge: 795

Danke es funktioniert. Jetzt hab ich auch gleich nach den Modulen geschaut.

Jetzt wäre noch eins, wie kann ich den Pfad angeben, dass er nur in diesen Verzeichnis schaut (wenn mehrere Dateien drin sind), und die älter sind als z.B. 3 Tage werden gelöscht?

Ich hab mir im Vorfeld dieses kleine Script gebastelt, womit das ja auch funktioniert, aber ich wollte mal ein "richtiges" Python Script basteln.

hier mein Script:

1
2
3
import os

os.system('find /home/matze/pyprobe/ -mmin +3 -delete') 

noisefloor Team-Icon

Anmeldungsdatum:
6. Juni 2006

Beiträge: 29567

Hallo,

hier mein Script:

os.system gilt als veraltet - steht sogar in der offiziellen Python Doku. Wenn du externe Befehle / Programme aufrufst, dann möchtest du das subprocess Modul nutzen.

Wenn du mit einem Datum rechnen willst, macht die Nutzung des datetime Moduls und von timedelta Objekten Sinn. Wie das geht hat seahawk1986 ja schon gezeigt.

Wenn du mal Verzeichnisse rekursiv durchlaufen willst, dann wirf' mal einen Blick auf die pathlib oder ggf. auch das glob Modul.

Gruß, noisefloor

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@matze31: Alternativ zum glob-Modul könnte auch os.listdir() und os.path.join() interessant sein und os.path.isfile() um gegebenenfalls Dateien von Verzeichnissen unterscheiden zu können.

Wenn wie beschrieben nur in einem Verzeichnis und nicht-rekursiv gelöscht werden soll, müsste man den find-Aufruf noch um eine Option erweitern um die Rekursion zu beschränken.

matze31

(Themenstarter)

Anmeldungsdatum:
25. Oktober 2015

Beiträge: 795

Ich hab mir jetzt mal "os.listdir" angeschaut und bin zu folgenden Ergebnis gekommen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import os
from datetime import datetime, timedelta
import time

a = '/home/matze/py/'

for f in os.listdir(a):
    
     file_mtime = datetime.fromtimestamp(os.path.getmtime(f))
     max_mtime = datetime.now() - timedelta(seconds=60)

     if file_mtime < max_mtime:
        os.remove(f)

Aber dann kommt das: "OSError: [Errno 2] No such file or directory: '3'"

In den Verzeichnis sind die Dateien 2 und 3 drin. Was mache ich jetzt noch falsch? ich arbeite mit Python 2.7

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@matze31: os.listdir() liefert Datei- und Verzeichnisnamen ohne den Pfad dort hin. Es gibt im aktuellen Arbeitsverzeichnis keine Datei mit dem Namen 3, daher die Ausnahme beim Versuch die Zeit von der Datei zu ermitteln. Und deshalb erwähnte ich os.path.join(). (An der Stelle wäre der komplette Traceback sinnvoll, denn da sieht man nicht nur was für eine Ausnahme es gab, sondern auch wo im Programm sie aufgetreten ist.

bernd_heller

Anmeldungsdatum:
21. November 2010

Beiträge: Zähle...

Hallo, ich habe mir erlaubt dein script durch das modul glob zu ergänzen.

So müsste es funktionieren:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import os, glob
from datetime import datetime, timedelta
import time

a = glob.glob('/home/matze/py/*)'

for f in a:
    
     file_mtime = datetime.fromtimestamp(os.path.getmtime(f))
     max_mtime = datetime.now() - timedelta(seconds=60)

     if file_mtime < max_mtime:
        os.remove(f)

Gruß Bernd

matze31

(Themenstarter)

Anmeldungsdatum:
25. Oktober 2015

Beiträge: 795

vielen dank, ihr seit super.

@ bernd_heller danke es funktioniert.

Jetzt habe ich es auch mit "os.listdir()" gelöst. hier mein Script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env python
import os
from datetime import datetime, timedelta
import time

b = os.path.expanduser('/home/matze/py')
for full in os.listdir(b):
     f = os.path.join(b, full)
     file_mtime = datetime.fromtimestamp(os.path.getmtime(f))
     max_mtime = datetime.now() - timedelta(seconds=60)

     if file_mtime < max_mtime:
        os.remove(f)

Jetzt nochmal eine Frage, gibt es ein sehr gutes Buch auf deutsch, wo die wichtigsten Module (wie dieses "os" und andere beschrieben sind? Es kann auch im Internet was sein.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

Etwas full zu nennen was so gar nicht vollständig, sondern nur ein Teil ist, verwirrt ein bisschen. Insbesondere wenn man dann den tatsächlichen vollen Pfad zu der Datei an den ziemlich nichtssagenden Namen f bindet.

os.path.expanduser() bewirkt im gezeigten Code genau gar nichts.

Und ich würde immer noch prüfen ob es sich um eine Datei handelt und/oder eine Ausnahmebehandlung mindestens für den Löschversuch schreiben.

matze31

(Themenstarter)

Anmeldungsdatum:
25. Oktober 2015

Beiträge: 795

OK danke. Gibt es ein Python ein Modul, mit dem man nach Endungen wie z.b. ".txt" finden kann? Ich möchte mein Script erweitern und in den Verzeichnis alle Dateien mit der Endung ".txt" löschen. Ich hab bisher noch nichts darüber gefunden.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@matze31: Das glob-Modul wurde bereits erwähnt. Und Du könntest natürlich auch einfach schauen ob der Dateiname mit '.txt' endet. Zeichenketten haben eine Menge nützlicher Methoden. ☺

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Mit Python >= 3.4 kann man auch pathlib nutzen:

1
2
3
4
5
6
7
8
from pathlib import Path
mydir = Path('/path/to/my/directory')
for p in mydir.glob('*.txt'):
   if p.is_file():
       try:
           p.unlink()
       except OSError as e:
           print("Could not delete {}: {}".format(p, e))
Antworten |