=========================

0. SETUP

=========================

$cartella = (Get-Location)

=========================

1. BACKUP AUTOMATICO

=========================

$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" $backup_dir = Join-Path $cartella "backuprinomina$timestamp"

New-Item -Path $backup_dir -ItemType Directory -Force | Out-Null

Get-ChildItem -Path $cartella -File | ForEach-Object {

non copiare i backup precedenti per evitare accumulo

if ($_.Name.StartsWith("backup_rinomina_")) { return }

Copy-Item -Path $_.FullName -Destination (Join-Path $backup_dir $_.Name) -Force

}

Write-Host "nBackup creato in: $backup_dirn"

=========================

2. COSTRUZIONE LISTA RINOMINE

=========================

$rinoMine = New-Object System.Collections.Generic.List[object] $destinazioni = New-Object System.Collections.Generic.HashSet[string]

regex: ^(\d+)(.*)$

$pattern = '^(?<numero>\d+)(?<resto>.*)$'

Get-ChildItem -Path $cartella -File | ForEach-Object {

evita lo script stesso

if ($_.Name -eq "rinomina.py") { return }

$nome = $_.BaseName   # stem
$estensione = $_.Extension

$m = [regex]::Match($nome, $pattern)
if (-not $m.Success) { return }

$numero = $m.Groups["numero"].Value
$resto  = $m.Groups["resto"].Value

# NON toccare file già a 3 cifre o più (100-999 ecc.)
if ($numero.Length -ge 3) { return }

$nuovo_numero = "{0:D3}" -f [int]$numero
$nuovo_nome = $nuovo_numero + $resto + $estensione

# controllo conflitti
if ($destinazioni.Contains($nuovo_nome)) {
    Write-Host "CONFLITTO: più file vogliono diventare $nuovo_nome"
    return
}

$destinazioni.Add($nuovo_nome) | Out-Null
$rinoMine.Add(@($_, $nuovo_nome))  # (file, nuovo_nome)

}

=========================

3. CONTROLLO PRELIMINARE

=========================

if ($rinoMine.Count -eq 0) { Write-Host "Nessun file da rinominare." Read-Host "Premi INVIO per uscire..." exit }

Write-Host "nANTEPRIMA RINOMINE:n"

ordinamento per nome file originale

$rinoMine | Sort-Object { $[0].Name } | ForEach-Object { $file = $[0] $nuovo = $_[1] Write-Host "$($file.Name) -> $nuovo" }

$risposta = (Read-Host "`nProcedere con la rinomina? (S/N): ").Trim().ToUpper()

if ($risposta -ne "S") { Write-Host "Operazione annullata." Read-Host "Premi INVIO per uscire..." exit }

=========================

4. RINOMINA SICURA A DUE PASSI

=========================

$temp_map = New-Object System.Collections.Generic.List[object]

PASSO 1: nomi temporanei (evita collisioni)

for ($i = 0; $i -lt $rinoMine.Count; $i++) { $file = $rinoMine[$i][0] $nuovo_nome = $rinoMine[$i][1]

$temp_name = "__temp__$i__$($file.Name)"
$temp_full = Join-Path $cartella $temp_name
$file_full = $file.FullName

Rename-Item -Path $file_full -NewName $temp_name
$temp_map.Add(@($temp_name, $nuovo_nome))

}

PASSO 2: nomi finali

foreach ($pair in $temp_map) { $temp_name = $pair[0] $nuovo_nome = $pair[1]

Rename-Item -Path (Join-Path $cartella $temp_name) -NewName $nuovo_nome

}

Write-Host "`nRinomina completata con successo." Read-Host "Premi INVIO per uscire..."