Rinominare i file presenti un una directory, soprattutto se sono un numero elevato, è un’operazione che può richiedere parecchio tempo e non può essere fatta manualmente. Questa necessità si presenta ad esempio quando si scaricano file da una fotocamera, si generano report automatici o bisogna gestire log di sistema.
In questo articolo vedremo uno script in Python con le seguenti caratteristiche
- Ordinare i file per data di creazione
- Applicare una numerazione progressiva a 4 cifre nel nome del file (0001, 0002…)
- Utilizzabile da riga di comando
- Ha una modalità anteprima (dry-run) che permette di vedere il risultato prima di eseguirlo realmente
Quindi se in una directory abbiamo dei file
$ ls -lart test/
total 4
-rw-r--r-- 1 carlo carlo 0 Mar 4 23:36 IMG_9384.jpg
-rw-r--r-- 1 carlo carlo 0 Mar 4 23:36 IMG_1021.jpg
-rw-r--r-- 1 carlo carlo 0 Mar 4 23:36 IMG_4432.jpg
-rw-r--r-- 1 carlo carlo 0 Mar 4 23:38 IMG_0012.jpg
-rw-r--r-- 1 carlo carlo 0 Mar 4 23:38 IMG_0247.jpgil risultato che vogliamo ottenere è
foto_0001.jpg
foto_0002.jpg
foto_0003.jpg
foto_0004.jpg
foto_0005.jpgseguendo l’ordine di creazione reale dei file, non quello alfabetico.
Lo script “RinominaFile.py”
import os
import argparse
import sys
def get_creation_time(path):
if sys.platform.startswith("win"):
return os.path.getctime(path)
else:
stat = os.stat(path)
return getattr(stat, "st_birthtime", stat.st_mtime)
parser = argparse.ArgumentParser(
description="Rinomina file ordinandoli per data di creazione."
)
parser.add_argument("cartella", help="Percorso della cartella")
parser.add_argument("--prefisso", default="file", help="Prefisso dei file")
parser.add_argument("--dry-run", action="store_true", help="Simula senza rinominare")
args = parser.parse_args()
files = [
f for f in os.listdir(args.cartella)
if os.path.isfile(os.path.join(args.cartella, f))
]
files.sort(key=lambda x: get_creation_time(os.path.join(args.cartella, x)))
contatore = 1
for nome_file in files:
percorso_vecchio = os.path.join(args.cartella, nome_file)
estensione = os.path.splitext(nome_file)[1]
nuovo_nome = f"{args.prefisso}_{contatore:04d}{estensione}"
percorso_nuovo = os.path.join(args.cartella, nuovo_nome)
if args.dry_run:
print(f"[ANTEPRIMA] {nome_file} → {nuovo_nome}")
else:
os.rename(percorso_vecchio, percorso_nuovo)
print(f"Rinominato: {nome_file} → {nuovo_nome}")
contatore += 1Per utilizzare lo script, da linea di comando possiamo eseguire
python RinominaFile.py /home/carlo/test --prefisso Foto --dry-run
# Output del comando
[ANTEPRIMA] IMG_9384.jpg → Foto_0001.jpg
[ANTEPRIMA] IMG_1021.jpg → Foto_0002.jpg
[ANTEPRIMA] IMG_4432.jpg → Foto_0003.jpg
[ANTEPRIMA] IMG_0012.jpg → Foto_0004.jpg
[ANTEPRIMA] IMG_0247.jpg → Foto_0005.jpgche permette di vedere quali sono le operazioni che verranno fatte sui file. Verificato che il risultato sia quello atteso, possiamo togliere l’opzione –dry-run per rinominare i file.
Analisi dello script
Nella prima parte dello script vengono importati i moduli necessari
import os
import argparse
import sysdove “os” viene utilizzato per l’interazione con il filesystem, “argparse” gestisce i parametri passati da linea di comando, “sys” rileva il sistema operativo
def get_creation_time(path):
if sys.platform.startswith("win"):
return os.path.getctime(path)
else:
stat = os.stat(path)
return getattr(stat, "st_birthtime", stat.st_mtime)In questa sezione viene gestito il recupero della data di creazione del file che è stato creato prendendo in considerazione il sistema operativo su cui si esegue lo script
- getctime() per sistemi Windows
- st_birthtime per sistemi MacOS
- st_mtime per sistemi Linux (non su tutte le distribuzioni esiste st_birthtime)
parser = argparse.ArgumentParser(
description="Rinomina file ordinandoli per data di creazione."
)
parser.add_argument("cartella", help="Percorso della cartella")
parser.add_argument("--prefisso", default="file", help="Prefisso dei file")
parser.add_argument("--dry-run", action="store_true", help="Simula senza rinominare")Legge i parametri passati dalla linea di comando. Il percorso della directory è obbligatorio, mentre il prefisso del file e la modalità dry-run sono opzionali
files = [
f for f in os.listdir(args.cartella)
if os.path.isfile(os.path.join(args.cartella, f))
]Questo passaggio legge tutto il contenuto della cartella specificata escludendo le sottocartelle
files.sort(key=lambda x: get_creation_time(os.path.join(args.cartella, x)))Per ogni file presente nella directory viene calcolata la data di creazione salvandola in una lista per poi ordinarla cronologicamente. In questo modo il primo file sarà quello più vecchio ed avrà nel nome l’indice 1
nuovo_nome = f"{args.prefisso}_{contatore:04d}{estensione}"Viene ora creato il nuovo nome del file concatenando il prefisso passato, il contatore a 4 cifre (0001, 0002, 0003, …) e l’estensione
if args.dry_run:
print(f"[ANTEPRIMA] {nome_file} → {nuovo_nome}")
else:
os.rename(percorso_vecchio, percorso_nuovo)Con l’opzione –dry-run nessun file viene modificato ma viene stampata la lista con le operazioni che verranno effettivamente fatte rieseguendo il comando senza l’opzione. In questo modo si riduce il rischio di errore nel processo di rinomina.
