Питхон скрипте за редовно брисање датотека

Redovno, ručno čišćenje datotečnog sistema nije idealno rešenje. Automatizujte taj proces!

Ručno brisanje datoteka i fascikli nije naročito uzbudljiv posao, kako bi se možda na prvi pogled učinilo. Mnogo je smislenije automatizovati taj postupak.

Tu u igru stupa Python, kako bi nam olakšao život. Python je izvanredan programski jezik za pisanje skripti. Iskoristićemo sve prednosti koje Python nudi kako bismo ovaj zadatak obavili bez ikakvih poteškoća. Prvo, neophodno je da razumete zašto je Python dobar izbor.

  • Python je uvek bio prvi izbor za automatizaciju zadataka
  • Zahteva manje koda u poređenju sa drugim programskim jezicima
  • Python je kompatibilan sa svim operativnim sistemima. Isti kod možete bez problema pokrenuti na Windows, Linux i macOS sistemima.
  • Python poseduje modul nazvan ‘os’ koji nam omogućava interakciju sa operativnim sistemom. Koristićemo ovaj modul kako bismo uspešno izvršili automatizaciju brisanja datoteka.

Sve dosadne ili ponavljajuće sistemske zadatke možemo zameniti korišćenjem Python-a. Pisanje skripti za obavljanje specifičnog sistemskog zadatka je prilično jednostavno ukoliko poznajete Python. Pogledajmo naredni primer.

Napomena: prikazani primeri su testirani na Python 3.6+ verzijama

Uklanjanje datoteka/foldera starijih od X dana

Često se javlja potreba za brisanjem starih log fajlova, kako bi se oslobodio prostor za skladištenje. Naravno, ne radi se samo o log fajlovima, već i o drugim vrstama datoteka.

Unutar ‘os’ modula imamo metodu koja se naziva ‘stat’, koja pruža detalje o vremenu poslednjeg pristupa (st_atime), izmene (st_mtime) i modifikacije metapodataka (st_ctime). Sve ove metode vraćaju vreme u sekundama od epohe. Više detalja o samoj epohi možete pronaći ovde.

Koristićemo metodu ‘os.walk(path)’ za kretanje kroz poddirektorijume određenog direktorijuma.

Pratite korake navedene u nastavku kako biste napisali kod za brisanje datoteka/foldera na osnovu broja dana.

  • Uvezite module: time, os i shutil
  • Definišite putanju i broj dana kao promenljive
  • Pretvorite broj dana u sekunde pomoću metode ‘time.time()’
  • Proverite da li putanja postoji ili ne, koristeći modul ‘os.path.exists(path)’
  • Ako putanja postoji, pribavite listu svih datoteka i fascikli koje se nalaze na toj putanji, uključujući i poddirektorijume. Koristite metodu ‘os.walk(path)’, koja će vratiti generator koji sadrži informacije o fasciklama, datotekama i podfasciklama.
  • Pribavite punu putanju do datoteke ili fascikle spajanjem trenutne putanje i imena datoteke/direktorijuma koristeći metodu ‘os.path.join()’
  • Pribavite ‘ctime’ vrednost pomoću metode ‘os.stat(path)’ i atributa ‘st_ctime’
  • Uporedite dobijeni ‘ctime’ sa vremenom koje smo ranije izračunali
  • Ukoliko je rezultat veći od definisanog broja dana, proverite da li je u pitanju datoteka ili fascikla. Ako je u pitanju datoteka, koristite ‘os.remove(path)’, u suprotnom koristite metodu ‘shutil.rmtree()’
  • Ukoliko putanja ne postoji, ispišite poruku da nije pronađena.

Pogledajmo detaljno kod.

# uvoz potrebnih modula
import os
import shutil
import time

# glavna funkcija
def main():

	# inicijalizacija brojaca
	deleted_folders_count = 0
	deleted_files_count = 0

	# specificiranje putanje
	path = "/PUTANJA_ZA_BRISANJE"

	# specificiranje broja dana
	days = 30

	# pretvaranje dana u sekunde
	# time.time() vraca trenutno vreme u sekundama
	seconds = time.time() - (days * 24 * 60 * 60)

	# provera da li datoteka postoji u okviru putanje
	if os.path.exists(path):
		
		# iteriranje kroz svaki folder i fajl u okviru putanje
		for root_folder, folders, files in os.walk(path):

			# poredjenje dana
			if seconds >= get_file_or_folder_age(root_folder):

				# uklanjanje foldera
				remove_folder(root_folder)
				deleted_folders_count += 1 # uvecavanje brojaca

				# prekidanje petlje nakon uklanjanja root_folder-a
				break

			else:

				# provera foldera iz root_folder-a
				for folder in folders:

					# putanja do foldera
					folder_path = os.path.join(root_folder, folder)

					# poredjenje sa brojem dana
					if seconds >= get_file_or_folder_age(folder_path):

						# pozivanje funkcije remove_folder
						remove_folder(folder_path)
						deleted_folders_count += 1 # uvecavanje brojaca


				# provera datoteka trenutnog direktorijuma
				for file in files:

					# putanja do datoteke
					file_path = os.path.join(root_folder, file)

					# poredjenje sa brojem dana
					if seconds >= get_file_or_folder_age(file_path):

						# pozivanje funkcije remove_file
						remove_file(file_path)
						deleted_files_count += 1 # uvecavanje brojaca

		else:

			# ako putanja nije direktorijum
			# poredjenje sa brojem dana
			if seconds >= get_file_or_folder_age(path):

				# pozivanje funkcije za uklanjanje datoteke
				remove_file(path)
				deleted_files_count += 1 # uvecavanje brojaca

	else:

		# fajl/folder nije pronadjen
		print(f'"{path}" nije pronadjen')
		deleted_files_count += 1 # uvecavanje brojaca

	print(f"Ukupno obrisanih foldera: {deleted_folders_count}")
	print(f"Ukupno obrisanih datoteka: {deleted_files_count}")


def remove_folder(path):

	# uklanjanje foldera
	if not shutil.rmtree(path):

		# poruka o uspesnom uklanjanju
		print(f"{path} je uspesno uklonjen")

	else:

		# poruka o neuspelom uklanjanju
		print(f"Nemoguce je obrisati {path}")



def remove_file(path):

	# uklanjanje datoteke
	if not os.remove(path):

		# poruka o uspesnom uklanjanju
		print(f"{path} je uspesno uklonjen")

	else:

		# poruka o neuspelom uklanjanju
		print(f"Nemoguce je obrisati {path}")


def get_file_or_folder_age(path):

	# dobijanje ctime datoteke/foldera
	# vreme ce biti u sekundama
	ctime = os.stat(path).st_ctime

	# vracanje vremena
	return ctime


if __name__ == '__main__':
	main()

Potrebno je da prilagodite sledeće dve promenljive u gornjem kodu na osnovu svojih zahteva.

days = 30 
path = "/PUTANJA_ZA_BRISANJE"

Uklanjanje datoteka većih od X GB

Potražimo datoteke koje su veće od određene veličine i obrišimo ih. Ovaj scenario je sličan prethodnom. U prethodnoj skripti smo koristili starost kao parametar, a sada ćemo uzeti veličinu kao parametar za brisanje.

# uvoz os modula
import os

# funkcija koja vraca velicinu datoteke
def get_file_size(path):

	# dobijanje velicine datoteke u bajtovima
	size = os.path.getsize(path)

	# vracanje velicine datoteke
	return size


# funkcija za brisanje datoteke
def remove_file(path):

	# brisanje datoteke
	if not os.remove(path):

		# uspeh
		print(f"{path} je uspesno obrisana")

	else:

		# greska
		print(f"Nemoguce je obrisati {path}")


def main():
	# definisanje putanje
	path = "UNESI_PUTANJU_OVDE"

	# definisanje maksimalne velicine datoteke u MB
	size = 500

	# provera da li putanja postoji
	if os.path.exists(path):

		# pretvaranje velicine u bajtove
		size = size * 1024 * 1024

		# prolazak kroz podfoldere
		for root_folder, folders, files in os.walk(path):

			# iteriranje kroz listu datoteka
			for file in files:
				
				# dobijanje putanje datoteke
				file_path = os.path.join(root_folder, file)

				# provera velicine datoteke
				if get_file_size(file_path) >= size:
					# pozivanje funkcije remove_file
					remove_file(file_path)
			
		else:

			# provera samo ako je putanja datoteka
			if os.path.isfile(path):
				# putanja nije dir
				# direktna provera fajla
				if get_file_size(path) >= size:
					# pozivanje funkcije remove_file
					remove_file(path)


	else:

		# putanja ne postoji
		print(f"{path} ne postoji")

if __name__ == '__main__':
	main()

Podesite sledeće dve promenljive.

path = "UNESI_PUTANJU_OVDE" 
size = 500

Uklanjanje datoteka sa određenom ekstenzijom

Možda ćete imati potrebu da obrišete datoteke prema njihovim tipovima ekstenzija. Na primer, sve .log fajlove. Ekstenziju datoteke možemo pronaći pomoću metode ‘os.path.splitext(path)’. Ova metoda vraća tuple koji sadrži putanju i ekstenziju datoteke.

# uvoz os modula
import os

# glavna funkcija
def main():
    
    # specificiranje putanje
    path = "PUTANJA_ZA_PRETRAGU"
    
    # specificiranje ekstenzije
    extension = ".log"
    
    # provera da li putanja postoji
    if os.path.exists(path):
        
        # provera da li je putanja direktorijum
        if os.path.isdir(path):
        
            # iteriranje kroz podfoldere
            for root_folder, folders, files in os.walk(path):
                
                # provera datoteka
                for file in files:

                    # putanja datoteke
                    file_path = os.path.join(root_folder, file)

                    # izvlacenje ekstenzije iz imena datoteke
                    file_extension = os.path.splitext(file_path)[1]

                    # provera ekstenzije datoteke
                    if extension == file_extension:
                        
                        # brisanje datoteke
                        if not os.remove(file_path):
                            
                            # poruka o uspesnom brisanju
                            print(f"{file_path} uspesno obrisana")
                            
                        else:
                            
                            # poruka o neuspesnom brisanju
                            print(f"Nemoguce je obrisati {file_path}")
        
        else:
            
            # putanja nije direktorijum
            print(f"{path} nije direktorijum")
    
    else:
        
        # putanja ne postoji
        print(f"{path} ne postoji")

if __name__ == '__main__':
    # pozivanje glavne funkcije
    main()

Ne zaboravite da ažurirate putanju i promenljivu ekstenzije u gornjem kodu kako biste ispunili svoje specifične zahteve.

Preporučujem da se skripte testiraju u okruženju koje nije produkcijsko. Kada budete zadovoljni rezultatima, možete zakazati njihovo izvršavanje putem cron-a (ako koristite Linux) kako bi se redovno pokretale radi održavanja. Python je odličan za postizanje ovakvih stvari, i ako ste zainteresovani da naučite više, pogledajte ovaj Udemy kurs.

Da li ste uživali čitajući ovaj članak? Šta kažete na to da ga podelite sa drugima?