Ik ben sinds 2 maanden met Linux begonnen, na jarenlang windows gebruikt te hebben. Meteen begonnen met "programmeren" in bash om een aantal zaken zoals backups te automatiseren. Ik heb ook een script gemaakt dat men foto-bestanden converteert naar de voor mij gewenste naamgeving. Ik weet dat hier kant en klare tools voor bestaan maar dit is ook als programmeer-oefening voor mezelf bestemd.
Ik heb een volledig werkend script. Elke keer ik op een probleem (zoals filenames met spaties) botste, heb ik het script aangepast/uitgebreid na zoekwerk op internet.
Ik zoek een meer ervaren iemand die men script nakijkt en eventueel suggesties doet waar het beter zou kunnen. In mijn ogen is het script wel enorm traag. Het draait ongeveer 4-5 minuten om 3000 bestanden te verwerken, wat me vrij traag lijkt. Voorheen had ik een java programma dat hetzelfde deed maar op een fractie van de tijd klaar was op dezelfde pc. Hieronder wat uitleg over de werking van het script en natuurlijk het script zelf.
Er zijn 2 hoofdfolders met foto's : /home/davy/Pictures/ en /home/davy/paradise/f/
In deze hoofdfolders zitten foto's, al dan niet bewaard in subfolders. Bestanden en folders kunnen spaties in hun naam hebben. Bedoeling is dat alle bestanden als naam de datum en het uur krijgen waarop de foto gemaakt is. Dit in het formaat YYYYMMDD_HHMMSS.jpg
De folders met naam "vanalles" moet door het script overgeslagen worden.
Er wordt voor elk bestand gekeken of deze al een geldige bestandsnaam hebben. Als deze een geldige bestandsnaam heeft (dus yyyymmdd_hhmmss.jpg voorbeeld 20081202_182600), dan wordt de modification time van het bestand aangepast met de timestamp uit de filenaam, wanneer deze niet moest overeenkomen. Dit zodat de modification time altijd zou kloppen daar deze al eens kan wijzigen na overzetten tussen windows en linux.
Als het bestand geen geldige bestandsnaam heeft, wordt het bestand hernoemt naar formaat YYYYMMDD_HHMMSS.jpg door de modification time van het bestand uit te lezen.
#!/bin/bash
echo "Update timestamp (y/n)?"
read upd_ts
echo "Update filename (y/n)?"
read upd_fn
folders="/home/davy/Pictures/ /home/davy/paradise/f/"
for i in $folders
do
find $i* -type f | while read x
do
# file without directory
old_filename=`basename "$x"`
# directory without file
old_foldername=`dirname "$x"`
if [[ "$old_foldername" = *vanalles* ]]
then
continue
fi
# filename without extension - deletes shortest match from back of string
old_singlename=${old_filename%.*}
# get old timestamp YYYYMMDDhhmmss
old_timestamp=${old_singlename:0:8}${old_singlename:9:4}.${old_singlename:13:2}
# file extension without point - deletes longest match from start of string
old_extension=${old_filename##*.}
# get date from filename and validate whether real timestamp
old_filename_yyyy=${old_singlename:0:4}
old_filename_mm=${old_singlename:4:2}
old_filename_mm=`echo $old_filename_mm|sed 's/^0*//'`
old_filename_dd=${old_singlename:6:2}
old_filename_dd=`echo $old_filename_dd|sed 's/^0*//'` # replace leading zeroes, otherwise bash thinks these are octals and fails test
old_filename_uu=${old_singlename:9:2}
old_filename_uu=`echo $old_filename_uu|sed 's/^0*//'` # replace leading zeroes, otherwise bash thinks these are octals
old_filename_mi=${old_singlename:11:2}
old_filename_mi=`echo $old_filename_mi|sed 's/^0*//'` # replace leading zeroes, otherwise bash thinks these are octals
old_filename_ss=${old_singlename:13:2}
old_filename_ss=`echo $old_filename_ss|sed 's/^0*//'` # replace leading zeroes, otherwise bash thinks these are octals
old_filename_strip_underscore="$(echo $old_singlename | sed 's/_//g')"
old_filename_strip_numerics="$(echo $old_filename_strip_underscore | sed 's/[0-9]//g')"
file_name_valid=0
old_filename_len=`echo "$old_filename_strip_underscore" | awk '{print length}'`
if [[ $old_filename_len != 14 ]]
then file_name_valid=0
elif [[ ! -z "$old_filename_strip_numerics" ||
$old_filename_strip_underscore -lt 20000000000000 ||
$old_filename_strip_underscore -gt 21000000000000 ||
$old_filename_yyyy -lt 2000 ||
$old_filename_yyyy -gt 2020 ||
$old_filename_mm -lt 1 ||
$old_filename_mm -gt 12 ||
$old_filename_dd -lt 1 ||
$old_filename_dd -gt 31 ||
$old_filename_uu -lt 0 ||
$old_filename_uu -gt 23 ||
$old_filename_mi -lt 0 ||
$old_filename_mi -gt 59 ||
$old_filename_ss -lt 0 ||
$old_filename_ss -gt 59 ]]
then
file_name_valid=0
else
file_name_valid=1
fi
new_filename=$(date -r "$x" +%Y%m%d_%H%M%S.$old_extension)
new_fullfilename=$old_foldername/$new_filename
if [[ "$file_name_valid" = 1 && "$old_filename" != "$new_filename" ]]
then
echo "File $old_filename will be restamped to $old_timestamp"
if [[ "$upd_ts" = "y" ]]
then touch -t $old_timestamp "$x"
fi
fi
if [[ "$file_name_valid" = 0 ]]
then
echo "File $old_filename will be renamed to $new_filename"
if [[ "$upd_fn" = "y" ]]
then
if [[ -f "$new_fullfilename" ]]; then
echo "New file already exists : $new_fullfilename"
else
mv "$x" "$new_fullfilename"
fi
fi
fi
done
done
exit 0