bash scripting help

Ken Moffat ken at
Thu Mar 24 05:48:53 PST 2005

On Thu, 24 Mar 2005, [ISO-8859-1] Sébastien Maerten wrote:

> JPG_Files > jhead 2005_0101_032039.jpg
> File name    : 2005_0101_032039.jpg
> File size    : 2377332 bytes
> File date    : 2005:01:01 03:20:42
> Camera make  : FUJIFILM
> Camera model : FinePix S602 ZOOM
> Date/Time    : 2005:01:01 03:20:39
> Resolution   : 2832 x 2128
> Flash used   : Yes (auto, red eye reduction mode)
> Focal length :  7.8mm  (35mm equivalent: 37mm)
> CCD width    : 7.65mm
> Exposure time: 0.017 s  (1/60)
> Aperture     : f/2.8
> ISO equiv.   : 200
> Whitebalance : Auto
> Metering Mode: matrix
> Exposure     : program (auto)
> I need to store the following information in variables: file name, file
> size, date/time, camera model, resolution. I'm doing it this way :
> for FILE in *.{jpg,JPG} ; do
>      jhead $FILE > temp
>      EXIF_NAME=`cat temp | grep "File name"  | cut -f 7 -d ' '`
>      EXIF_SIZE=`cat temp | grep "File size"  | cut -f 7 -d ' '`
>      EXIF_DATE=`cat temp | grep "Date/Time"  | cut -f 6,7 -d ' '`
>      EXIF_RESO=`cat temp | grep "Resolution" | cut -f 5,7 -d ' '`
>      printf "NAME: %s\tSIZE: %s\tDATE: %s %s\tRESO: %s x %s\n"
>      rm temp
>      echo ""
> done
> The problem: this is really long since there are many files (38
> minutes). I guess it comes from the temp file writing / reading, but my
> knowledge is to small to figure a better way to get the information I
> need. Any ideas on how to parse the output of jhead in one pass ?
> Any comment is welcome.

First comment: you've done it once, is it really important enough to
spend more time trying to optimise it ?

Second comment: from here, it looks like a problem for 'awk' (printing
fields from the input) - just get the data for the file into one line
with constant delimiters.

  My first thought was to use sed to change the first ':' on each line,
e.g. to '|', and tr to convert the newlines to another '|'.  That
doesn't work, sed is always greedy so it trashes the last ':' in the
time field.

 If I was a perl programmer, this would look like a perl problem, but
I'm not ;)  I compromised with a one-liner in perl to change the first
':', plus tr and awk.  I'm sure a perl programmer could do it as a
single script that runs a lot faster, perhaps invoking jhead in the
script so that you just pass the file names and keep the script
resident.  Took a quick look at a2p and decided it wasn't for me ;)

 What I've got (starting with the output from jhead) is

| perl -p -e 's/:/|/' \
| tr '\n' '|' \
| awk -F '|' '{ print "NAME:" $2 " SIZE:" $4 " DATE:" $12
 " CAMERA:" $10 " RESO:" $14 }'

 I guess the awk will probably not like being split across lines, but I
guessed the mailer would wrap it funny if I didn't.

 Note that the data fields contain multiple space-delimited values, I
haven't attempted to use tabs, and the "keywords" (like RESO:) need a
preceding space to stop the previous data running into them.

 If I was really keen, I'd try doing it all in perl, but I've only got
another hour or so waiting for my current compilation to finish, and I
can tell that won't be long enough for me to do it :)

 das eine Mal als Tragödie, das andere Mal als Farce

More information about the lfs-chat mailing list