Cambiare data alle Foto da Linux

 

In realtà, lo script che ho realizzato, può cambiare data a qualsiasi file ma, lo scopo principale, è quello di modificarla alle foto che, quando – puntualmente – vengono importante, presentano una data sballata.

Per utilizzarlo – ahimè – è richiesto l’uso del terminale e quindi non particolarmente pratico ma, se non altro, è gratuito e mi risulta funzionare piuttosto bene.

Come prima cosa è necessario fare un copia/incolla in un file che andremo a chiamare uda_change_time.sh del seguente codice:

#!/bin/bash

# Script per cambiare la data ai files specificati.

# $Date: 2012/12/25 11:31:46 $
# $Revision: 1.5 $
# By UDA'Software 2012

################################################################################
#_______________________________________________________________________________
function print_help() {
    printf 'Sintassi: %s [--help] <ora> <minuti> <secondi> <giorni> <mesi> <anni> <file> [OPTIONS]\n' "${0}"

    cat<<EOF

Scopo dello script e' quello di modificare la data e l'ora dei files
specificati,aggiungendo o sottraendo "tempo".

Il "tempo" viene specificato con 6 parametri, che possono essere
positivi o negativi - aggiungendo il segno "-" (meno) -, rappresentati
l'entità che si vuole andare, rispettivamente, ad aggiungere o
togliere alla data corrente dei files che verranno elaborati.

Ad esempio:

${0} 5 -30 20 4 -3 10 miafoto.jpg

produce come effetto che alla data di creazione del file "miafoto.jpg"
saranno aggiunte 5 ore, sottratti 30 minuti, aggiunti 20 secondi,
aggiunti 4 giorni, sottratti 3 mesi e aggiunti 10 anni.

Volendo elaborare piu' files contemporaneamente e' possibile
utilizzare i caratteri jolly; ad esempio:

${0} 5 -30 20 4 -3 10 '*.jpg'

OPZIONI

E' possibile utilizzare delle opzioni che modificano il comportamento
base dello script, ovvero:

	--test
		Modalita' di simulazione; non esegue nessuna modifica,
		aiuta solo a capire come la data dei files specificati
		verra' modificata.

	--ask
		Modalita' di richiesta; prima di procedere alla
		modifica dei files specificati, chiede conferma. Con
		la risposta "a" si ottiene l'interruzione definitiva.

	--current
		Ignora i parametri - relativi al tempo di modifica - e
		utilizza la data corrente per stabilire quella che
		dovranno assumere i files specificati.

EOF
    exit 0;
}

################################################################################
#_______________________________________________________________________________
function calcola_max_giorni() {
    case ${file_mese} in
	1) # Gennaio
	    max_giorni=31
	    ;;
	2) # Febbraio
	    if (( (anno % 400) == 0 )) || (( (anno % 4) == 0 && (anno % 100) != 0 )); then
		max_giorni=29
	    else
		max_giorni=28
	    fi
	    ;;
	3) # Marzo
	    max_giorni=31
	    ;;
	4) # Aprile
	    max_giorni=30
	    ;;
	5) # Maggio
	    max_giorni=31
	    ;;
	6) # Giugno
	    max_giorni=30
	    ;;
	7) # Luglio
	    max_giorni=31
	    ;;
	8) # Agosto
	    max_giorni=31
	    ;;
	9) # Settembre
	    max_giorni=30
	    ;;
	10) # Ottobre
	    max_giorni=31
	    ;;
	11) # Novembre
	    max_giorni=30
	    ;;
	12) # Dicembre
	    max_giorni=31
	    ;;
    esac
}

################################################################################
#_______________________________________________________________________________
ora="${1:-0}"
minuti="${2:-0}"
secondi="${3:-0}"
giorno="${4:-0}"
mese="${5:-0}"
anno="${6:-0}"
files="${7}"

if [ "${1}" == "--help" ]; then
    print_help
fi

if [ "${files}" == "" ]; then
    printf 'ERRORE: Non hai specificato i paramatri correttamente.\nUsare: %s --help\n' "${0}"

    exit 1;
fi

while [ "$8" != "" ]; do
    case ${8} in
	"--test")
	    flag_test=1
	    printf '(Attivata la modalita'\'' simulazione)\n'
	    ;;
	"--ask")
	    flag_ask=1
	    printf '(Attivata la modalita'\'' richiesta di modifica)\n'
	    ;;
	"--current")
	    flag_current=1
	    printf '(Attivata la modalita'\'' data corrente)\n'
    esac

    shift
done

################################################################################
#_______________________________________________________________________________
if [ ${flag_current:-0} == 0 ]; then
    if [ ${ora} -lt 0 ]; then
	printf '* All'\''orario saranno sottratte %d ore\n' ${ora/-/}
    else
	printf '* All'\''orario saranno aggiunte %d ore\n' ${ora/-/}
    fi

    if [ ${minuti} -lt 0 ]; then
	printf '* All'\''orario saranno sottratte %d minuti\n' ${minuti/-/}
    else
	printf '* All'\''orario saranno aggiunte %d minuti\n' ${minuti/-/}
    fi

    if [ ${secondi} -lt 0 ]; then
	printf '* All'\''orario saranno sottratte %d secondi\n' ${secondi/-/}
    else
	printf '* All'\''orario saranno aggiunte %d secondi\n' ${secondi/-/}
    fi

    if [ ${giorno} -lt 0 ]; then
	printf '* Alla data saranno sottratti %d giorni\n' ${giorno/-/}
    else
	printf '* Alla data saranno aggiunti %d giorni\n' ${giorno/-/}
    fi

    if [ ${mese} -lt 0 ]; then
	printf '* Alla data saranno sottratti %d mesi\n' ${mese/-/}
    else
	printf '* Alla data saranno aggiunti %d mesi\n' ${mese/-/}
    fi

    if [ ${anno} -lt 0 ]; then
	printf '* Alla data saranno sottratti %d anni\n' ${anno/-/}
    else
	printf '* Alla data saranno aggiunti %d anni\n' ${anno/-/}
    fi
fi

for file in ${files}; do
    if [ -f ${file} ]; then
	printf 'Elaborazione del file: %s\n' "${file}"

	file_timestamp=$(stat --printf=%Y ${file})

	file_ora=$(date +%H --date="@${file_timestamp}" | sed 's@^0@@')
	file_minuti=$(date +%M --date="@${file_timestamp}" | sed 's@^0@@')
	file_secondi=$(date +%S --date="@${file_timestamp}" | sed 's@^0@@')
	file_giorno=$(date +%d --date="@${file_timestamp}" | sed 's@^0@@')
	file_mese=$(date +%m --date="@${file_timestamp}" | sed 's@^0@@')
	file_anno=$(date +%Y --date="@${file_timestamp}" | sed 's@^0@@')

	printf '  Data corrente   : %02d:%02d:%02d %02d/%02d/%04d\n' ${file_ora} ${file_minuti} ${file_secondi} ${file_giorno} ${file_mese} ${file_anno}

	if [ ${flag_current:-0} == 0 ]; then
	    delta_timestamp=$(($((${ora} * 3600)) + $((${minuti} * 60)) + ${secondi}))
	    file_timestamp=$((${file_timestamp} + ${delta_timestamp}))

	    file_ora=$(date +%H --date="@${file_timestamp}" | sed 's@^0@@')
	    file_minuti=$(date +%M --date="@${file_timestamp}" | sed 's@^0@@')
	    file_secondi=$(date +%S --date="@${file_timestamp}" | sed 's@^0@@')

	    file_anno=$(($(date +%Y --date="@${file_timestamp}" | sed 's@^0@@') + ${anno}))
	    file_mese=$(($(date +%m --date="@${file_timestamp}" | sed 's@^0@@') + ${mese}))
	    if [ ${file_mese} -gt 12 ]; then
		file_mese=1
		file_anno=$((${file_anno} + 1))
	    elif [ ${file_mese} -lt 1 ]; then
		file_mese=12
		file_anno=$((${file_anno} - 1))
	    fi

	    calcola_max_giorni

	    file_giorno=$(($(date +%d --date="@${file_timestamp}" | sed 's@^0@@') + ${giorno}))
	    if [ ${file_giorno} -gt ${max_giorni} ]; then
		file_giorno=1
		file_mese=$((${file_mese} + 1))

		if [ ${file_mese} -gt 12 ]; then
		    file_mese=1
		    file_anno=$((${file_anno} + 1))
		fi
	    elif [ ${file_giorno} -lt 1 ]; then
		file_mese=$((${file_mese} - 1))
		if [ ${file_mese} -lt 1 ]; then
		    file_mese=12
		    file_anno=$((${file_anno} - 1))
		fi

		calcola_max_giorni

		file_giorno=${max_giorni}
	    fi
	else
            file_ora=$(date +%H)
            file_minuti=$(date +%M)
            file_secondi=$(date +%S)
            file_giorno=$(date +%d)
            file_mese=$(date +%m)
            file_anno=$(date +%Y)
	fi

	if [ ${flag_test:-0} == 0 ]; then
	    if [ ${flag_ask:-0} == 0 ]; then
		answer="S"
	    else
		printf '  Data prevista   : %02d:%02d:%02d %02d/%02d/%04d\n' ${file_ora} ${file_minuti} ${file_secondi} ${file_giorno} ${file_mese} ${file_anno}
		printf 'Vuoi modificare la data del file  %s  ? (S/n/a)\n'
		read answer

		if [ "${answer}" == "a" ] || [ "${answer}" == "A" ]; then
		    printf '\nABORTITO !\n'

		    exit 0;
		fi
	    fi

	    if [ "${answer}" != "n" ] && [ "${answer}" != "N" ]; then
		printf '  Data modificata : %02d:%02d:%02d %02d/%02d/%04d\n' ${file_ora} ${file_minuti} ${file_secondi} ${file_giorno} ${file_mese} ${file_anno}

		file_ora=$(printf '%02d\n' ${file_ora})
		file_minuti=$(printf '%02d\n' ${file_minuti})
		file_secondi=$(printf '%02d\n' ${file_secondi})
		file_giorno=$(printf '%02d\n' ${file_giorno})
		file_mese=$(printf '%02d\n' ${file_mese})
		file_anno=$(printf '%04d\n' ${file_anno})

		touch -c -t ${file_anno}${file_mese}${file_giorno}${file_ora}${file_minuti}.${file_secondi} "${file}"
	    fi
	else
	    printf '  Data prevista   : %02d:%02d:%02d %02d/%02d/%04d\n' ${file_ora} ${file_minuti} ${file_secondi} ${file_giorno} ${file_mese} ${file_anno}
	fi
    else
	printf 'ERRORE: File  %s  non trovato !\n' "${file}"
    fi
done

################################################################################
#_______________________________________________________________________________

Dopodiché, andremo a renderlo eseguibile, sempre da terminale, con il seguente comando:

chmod +x uda_change_time.sh

 

Se il file viene salvato in un percorso come “/usr/local/bin”, sarà possibile invocarlo da qualsiasi cartella.

Per utilizzarlo è sufficiente rendere corrente la cartella dove sono presenti le foto; ad esempio ho usato il comando “mount” per sapere dove era stata montata la schedina della macchina fotografica e, successivamente, un comando simile al seguente:

cd /media/Untitled/DCIM/101SCAM

Inizialmente bisogna capire che genere di modifica bisogna apportare ai files; nella speranza che la data sia “rovinata” in egual modo (anche se comunque ho previsto la possibilità di modificarla selettivamente ai files interessati) si può iniziare operando con un comando come il seguente:

uda_change_time.sh 0 0 0 0 0 0 '*.JPG' --test

In questo modo si verifica subito quali files verranno elaborati e la rispettiva data.

Notare i parametri “0”; sono rispettivamente i modificatori di ora, minuti, secondi, giorni, mesi, anni.

Possono essere anche negativi, anteponendo il segno “-” (meno). Supponendo che la data dei files sia da portare indietro di 5 anni, avanti di 3 mesi, indietro di 1 giorno e con l’orario inalterato, potremmo verificare l’operazione con:

uda_change_time.sh 0 0 0 -1 3 -5 '*.JPG' --test

 

Togliendo l’opzione “–test” si va effettivamente ad eseguire la modifica; prima di apportare la modifica, consiglio di controllare bene che tutto venga modificato come previsto (lo script propone la data corrente e quella prevista per ogni file da elaborare).

Per evitare pasticci si può utilizzare l’opzione “–ask”, in modo che lo script chieda conferma per ogni file.

Per la guida dello script usare:

uda_change_time.sh --help

Per problemi o dubbi, non esitate a contattarmi.

Sia ben chiero: non mi assumo nessuna responsabilità nel caso in cui andiate a “danneggiare” qualche file con l’uso proprio o improprio dello script proposto.