6
\$\begingroup\$

I have snapshots (photos) that I load off my camera's memory card, and store in a folder. Sometimes I have videos, and occasionally plain audio too (the camera can record just sound).

Additionally, my wife, and kids have their point-and-shoots too.

I have a workflow where I dump the photos on to a designated folder on a linux samba share, and then run this script which identifies the photos, auto-rotates the portrait picturs, and renames them according to the date and time the picture was taken (rather than a sequential number from the camera).

This way, assuming the various cameras have the correct clock-time set, the different cameras all have photos that are named similar things (and can be sorted alphabetically to get them in chronological order too.

Notes:

  • the jhead program the script calls will rename/rotate the photos, and the name will become something like: Img20140217-164850.20.jpg
  • the jhead also identifies that some pictures may have 'raw' partners, for example, my Nikon camera takes a picture called DSC1234.JPG and simultaneously the picture DSC1234.NEF (the raw photo). The command jhead -aNEF -ft -autorot -n DSC*.JPG will identify the JPG photo, strip the .JPG extensions, and, because there is also the -aNEF argument, will rename the matching NEF file to the same base-name (Img*) as the JPG.... in other words, for the files DSC1234.JPG and DSC1234.JPG, the jhead program will produce, for example, both Img20140217-164850.20.jpg and Img20140217-164850.20.NEF
  • the script deals with both Canon, and Nikon raw files (RW2 and NEF respectively)

The script is relatively simple, but has a fair amount of repetition. Any suggestions for how to improve it?

#!/usr/bin/tcsh -f

#cd /valuable/picxfer

# Do the .jpg first because the jhead program will write .jpg even for .JPG input.
echo 'Checking DSC*.jpg'
if ( `tcsh -f -c "ls -1 DSC*.jpg >& /dev/null" && echo yes` == "yes" ) then
  jhead -anef -ft -autorot -n DSC*.jpg
else
  echo no Nikon jpg files
endif

echo 'Checking DSC*.JPG'
if ( `tcsh -f -c "ls -1 DSC*.JPG >& /dev/null" && echo yes` == "yes" ) then
  jhead -aNEF -ft -autorot -n DSC*.JPG
else
  echo no Nikon JPG files
endif


echo 'Checking *.jpg'
if ( `tcsh -f -c "ls -1 p*.jpg >& /dev/null" && echo yes` == "yes" ) then
  jhead -arw2 -ft -autorot -n p*.jpg
else
  echo no Canon jpg files
endif

echo 'Checking *.JPG'
if ( `tcsh -f -c "ls -1 P*.JPG >& /dev/null" && echo yes` == "yes" ) then
  jhead -aRW2 -ft -autorot -n P*.JPG
else
  echo no Canon JPG files
endif


echo Setting permissions
chmod ugo=r Img*
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Your if conditions can be simplified. Instead of this:

if ( `tcsh -f -c "ls -1 DSC*.jpg >& /dev/null" && echo yes` == "yes" ) then

You could write like this:

if ( `ls DSC*.jpg >& /dev/null && echo x` != "" ) then

That is:

  • you don't need to spawn a tcsh sub-shell
  • you don't need the -1 for ls to list files in a single column because you redirect that to /dev/null anyway
  • the `...` part will only output anything if there were files, so you don't need yes == yes, it's enough to check for emptiness

If you don't mind using Bash instead of Tcsh, then the ifs can be even more simple:

if ls DSC*.jpg &> /dev/null; then

A lot less useless fluff.

With Bash you could simplify the repetitive blocks with a function, for example:

check_files() {
    glob=$1
    flags=$2
    nomsg=$3
    echo Checking "$glob"
    if ls $glob &>/dev/null; then
        jhead -a$flags -ft -autorot -n $glob
    else
        echo $nomsg
    fi
    echo
}

check_files 'DSC*.jpg' nef 'no Nikon jpg files'
check_files 'DSC*.JPG' NEF 'no Nikon JPG files'
check_files 'p*.jpg' rw2 'no Canon jpg files'
check_files 'P*.JPG' RW2 'no Canon JPG files'
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.