nerd Här ser du hela skriptet med mina kommentarer, men det är nog lättare att se om du laddar hem det och tittar i en texteditor.

Som du ser använder jag bash skript med mycket awk.

#!/bin/bash

# -------------------------------------------------------------------
#
# Shell program för att namna om filer med sin tidsstämpel.
#
# Copyright 2006 - 2007, Ingemar Ceicer <programmering '@' ceicer.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# Deskription:
#
# Ett skript som namnändrar och kopierar bildfiler och ger den namn efter EXIF data.
# Format: YYYY-MM-DD_HH-MM-SS
# Skriptet använder programmet 'exif' för att exif data från filen.
# 'exif' har jag skrivit i C++. Det innebär en betydande förbättring jämfört med det gammla
# skriptet.
# Alla filer i den katalog du anger som källa och som har rätt filändelse kommer att kopieras
# till den katalog du angett som destination.
# Du kan använda '.' för att ange current directory som källa/destination.
# Tidsstämpeln från originalfilen överförs till den nya filen, så att inte tidsstämplingen skall
# gå förlorad vid kopieringen.
#
#
#
# Användning:
#
# cptime [ -h | --help ] [-s source] [-d destination] [-e extension] [-n name] [-u] [-l] [-t] [-v] [-c] [-a]
#
# Möjligheter:
#
# -h, --help Visa denna hjälptext och avsluta.
# -s källa Sökvägen till katalogen med källfilerna
# -d destination Sökvägen till destinationskatalogen
# -e ändelse Filändelsen (eller slutet på filen) på de filer som skall kopieras. (Inklusive '.')
# -n namn Det namn som man kan lägga till före datum/tid
# -a Lägger till det ursprungliga filnamnet före datum/tid. (med '_' mellan)
# -u Ändrar filändelsen till UPPER CASE på de kopierade filerna
# -l Ändrar filändelsen till lower case på de kopierade filerna
# -t Visar alla källfiler, destinationsfiler och tidsstämpeln utan att göra någon kopiering
# -v Visar alla källfiler, destinationsfiler och tidsstämpeln under kopieringen
# -c Avbryter med ett felmeddelande om du använder ett osäkert/felaktigt filnamn
#
# Exempel:
# $>cptime -s . -d newfiles -e .JPG -l -a
# Kopierar alla filer i katalogen du står i till underkatalogen 'newfiles'
# om de har filändelsen '.JPG', lägger till gamla filnamnet och '_' före
# datum/tid och ändrar JPG till jpg
# Således: 'image_0022.JPG' blir 'image_0022_2006-10-15_20-42-21.jpg'
#
#
#
# Revision History:
# 2006-10-13 V 0.0.1
# 2006-11-05 V 0.0.2
#
# -------------------------------------------------------------------

# Constants

PROGNAME=$(basename $0)
VERSION="0.0.2"

 

# Basala Functions

function error_exit
{

# -----------------------------------------------------------------------
# Function for exit due to fatal program error
# Accepts 1 argument:
# string containing descriptive error message
# -----------------------------------------------------------------------

echo "${PROGNAME}: ${1:-"Unknown Error"}" >&2

exit 1
}

function graceful_exit
{

# -----------------------------------------------------------------------
# Function called for a graceful exit
# No arguments
# -----------------------------------------------------------------------


exit
}

function signal_exit
{

# -----------------------------------------------------------------------
# Function to handle termination signals
# Accepts 1 argument:
# signal_spec
# -----------------------------------------------------------------------

case $1 in
INT) echo "$PROGNAME: Programmet avslutat av användaren" >&2
exit
;;
TERM) echo "$PROGNAME: Programet avslutades" >&2
exit
;;
*) error_exit "$PROGNAME: Programmet avslutades av okänd nledning"
;;
esac
}

function usage
{

# -----------------------------------------------------------------------
# Function to display usage message (does not exit)
# No arguments
# -----------------------------------------------------------------------

echo "Användning: ${PROGNAME} [-h | --help | --hjälp] [-s källa] [-d destination] [-e ändelse] [-n namn] [-u] [-l] [-t] [-v] [-c] [-a]"
}

function helptext
{

# -----------------------------------------------------------------------
# Function to display help message for program
# No arguments
# -----------------------------------------------------------------------

local tab=$(echo -en "\t\t")

cat <<- -EOF-

${PROGNAME} ver. ${VERSION}
Shell program för att namna om filer med sin exif data.

Ett skript som namnändrar och kopierar bildfiler och ger den namn efter EXIF data.
Format: YYYY-MM-DD_HH-MM-SS
Skriptet använder programmet 'exif' för att hämta exif data från filen.
'exif' har jag skrivit i C++. Det innebär en betydande förbättring jämfört med det gammla
skriptet.
Alla filer i den katalog du anger som källa och som har rätt filändelse kommer att kopieras
till den katalog du angett som destination.
Du kan använda '.' för att ange current directory som källa/destination.
Tidsstämpeln från originalfilen överförs till den nya filen, så att inte tidsstämplingen skall
gå förlorad vid kopieringen.

$(usage)

Möjligheter:

-h, --help, --hjälp Visa denna hjälptext och avsluta.
-s källa Sökvägen till katalogen med källfilerna
-d destination Sökvägen till destinationskatalogen
-e ändelse Filändelsen (eller slutet på filen) på de filer som skall kopieras. (Inklusive '.')
-n namn Det namn som man kan lägga till före datum/tid
-a Lägger till det ursprungliga filnamnet före datum/tid. (med '_' mellan)
-u Ändrar filändelsen till UPPER CASE på de kopierade filerna
-l Ändrar filändelsen till lower case på de kopierade filerna
-t Visar alla källfiler, destinationsfiler och tidsstämpeln utan att göra någon kopiering
-v Visar alla källfiler, destinationsfiler och tidsstämpeln under kopieringen
-c Avbryter med ett felmeddelande om du använder ett osäkert/felaktigt filnamn

Exempel:
$>cptime -s . -d newfiles -e .JPG -l -a
Kopierar alla filer i katalogen du står i till underkatalogen 'newfiles'
om de har filändelsen '.JPG', lägger till gamla filnamnet och '_' före
datum/tid och ändrar JPG till jpg
Således: 'image_0022.JPG' blir 'image_0022_2006-10-15_20-42-21.jpg'

-EOF-
}

# -------------------------------------------------------------------
# Program starts here
# -------------------------------------------------------------------

##### Initialization And Setup #####
# Trap TERM, HUP, and INT signals and properly exit

trap "signal_exit TERM" TERM HUP
trap "signal_exit INT" INT

##### Command Line Processing #####

if [[ "$1" = "--help" || "$1" = "--hjälp" ]]; then
helptext
graceful_exit
fi
echo
while getopts ":hs:d:e:n:ultvca" opt; do
case $opt in
s ) #echo "Sökvägen till katalogen med källfilerna - källa = $OPTARG"
s=$OPTARG ;;
d ) #echo "Sökvägen till destinationskatalogen - destination = $OPTARG"
d=$OPTARG ;;
e ) #echo "Filändelsen (eller slutet på filen) på de filer som skall kopieras - ändelse = $OPTARG"
ext=$OPTARG ;;
n ) #echo "Det namn som man kan lägga till före datum/tid - argument = $OPTARG"
name=$OPTARG ;;
a ) #echo "Lägger till det ursprungliga filnamnet före datum/tid. (med '_' mellan)"
name="append" ;;
u ) #echo "Ändrar filändelsen till UPPER CASE på de kopierade filerna"
lage="upper" ;;
l ) #echo "Ändrar filändelsen till lower case på de kopierade filerna"
lage="lower" ;;
t ) #echo "Visar alla källfiler, destinationsfiler och tidsstämpeln utan att göra någon kopiering"
test=1 ;;
v ) #echo "Visar alla källfiler, destinationsfiler och tidsstämpeln under kopieringen"
verbuse=1 ;;
c ) #echo "Avbryter med ett felmeddelande om du använder ett osäkert/felaktigt filnamn"
secure_filename=1 ;;

h ) helptext
graceful_exit ;;
* ) usage
;;
esac
done

if [ "$ext" = "" ] #en filnamnsextenson måste alltid finnas
then
usage
error_exit "Vänligen ange en filändelse."
fi

if [ $s ] #testar om källan angets
then

if [ ! -d $s ]; then #Kollar om källkatalogen verkligen existerar
usage
error_exit "Sökvägen till källfilerna existerar inte!"
fi

l=$(echo $s | awk '{print length($1)}') #lägger till '/' i slutet på sökvägen till källkatalogen
k=$(echo $s $l | awk '{print substr($1,$2,1)}') #om det inte redan finns
if [ $k != "/" ]; then
kall_path=$(echo $s "/" | awk '{print $1 $2}') #lägger, vid behov, till '/'
filer2=$(echo $s "/" | awk '{print $1 $2}')
filer=$(echo `ls $filer2`) #alla filer i källkatalogen fångas i $filer
else
kall_path=$s
filer=$(echo `ls $s`) #alla filer i källkatalogen fångas i $filer
fi
fi

if [ $d ] #testar om destinationen angets
then

if [ $d != "." ]; then
if [ ! -d $d ]; then
usage
error_exit "Destinationssökvägen existerar inte."
fi
l=$(echo $d | awk '{print length($1)}') #lägger till '/' i slutet på sökvägen till destinationskatalogen
s=$(echo $d $l | awk '{print substr($1,$2,1)}') #om det inte redan finns
if [ $s != "/" ]; then
copy_path=$(echo $d "/" | awk '{print $1 $2}')
else
copy_path=$d
fi

else
copy_path=$(echo `pwd` | awk '{print $0 "/"}')

fi
else
usage
error_exit "Vänligen ange dstinationskatalog."
fi

if [ $name ]; then #testar för ogiltiga filnamn
if [ $secure_filename ]; then
tst=$(echo $name | awk '{print /[^A-Za-z0-9_\-]/}') #Endas A-Z, a-z, 0-9, _ och -
if [ $tst == 1 ]; then
error_exit "Du använder inget säkert filnamn!"
fi
fi
fi

i=0
for f in [ $filer ] #alla filer i källkatalogen testas för ev. kopiering
do
namn_langd=$(echo $f | awk '{print length($0)}') #längden på filnamnet
ext_langd=$(echo $ext | awk '{print length($0)}') #längden på filändelsen
let start=$namn_langd-$ext_langd+1
ext_string=$(echo $f $start $ext_langd | awk '{print substr($1,$2,$3)}') #plockar ut filändelsen
if [ $ext_string == $ext ] #Kollar om det är en fländelse som stämmer med den angivna
then
if [ $name ] #Om namn angets
then

if [ $name = "append" ] #append medför att gamla filnamnet behålls före tidsangivelsen
then

let borgan=$start-1
namn_strang=$(echo $f $borgan | awk '{print substr($1,1,$2)}') #plockar ut gamla namnet (utan ändelsen)
a=$(echo $namn_strang "_" | awk '{print $1 $2}')
else
a=$name"_" #eget, nytt namn läggs före datum/tid
fi
else
a="" #om inte extra filnamn skall användas
fi
#plocka ut datum och tid med 'exif'
kalla=$(echo $kall_path $f | awk '{print $1 $2}')
tmp=$(echo `./exif "$kalla" --good`)
if [[ $lage == "lower" || $lage == "upper" ]]; then #Skall det ändras på filändelsen?
case "$lage" in #kollar om det skall vara små eller STORA bokstäver
"upper" ) ext2=$(echo $ext | awk '{print toupper($1)}') ;;
"lower" ) ext2=$(echo $ext | awk '{print tolower($1)}') ;;
esac
else
ext2=$ext
fi

 

# ':' i filnamn fungerar inte i Microsoft Windows
filname=$(echo $a $tmp $ext2 | awk '{print $1 $2 $3}' | awk '{sub(/:/,"-",$0); print}' | awk '{sub(/:/,"-",$0); print}')
tidstamp=$(echo $tmp | awk '{sub(/-/,"",$0); print}' | awk '{sub(/-/,"",$0); print}' | awk '{sub(/_/,"",$0); print}' | awk '{sub(/:/,"",$0); print}' | awk '{sub(/:/,".",$0); print}')
dest=$(echo $copy_path $filname| awk '{print $1 $2}')

if [[ $test || $verbuse ]]; then
printf "%-12s %s \n" Källa: $kalla
printf "%-12s %s \n" Destination: $dest
# printf "%-12s %s \n\n" Tidsstämpel: $tidstamp
fi

if [ ! $test ]; then
cp $kalla $dest 1>/dev/null
# touch -t $tidstamp $dest 1>/dev/null
let "i += 1" #antalet kopierade filer
fi

fi
done

echo "$i filer kopierade och namn ändrade"
echo

graceful_exit