I wanted to rename a number of JPG files in a directory and I wanted to use BASH as it is amazing powerful yet I don’t understand it as well as I want, so I took the time to find a method shown on numerous forums and sites and then understand what it is doing. Here is the script, or line I used:
for f in `find . -name ‘*.JPG’` ; do mv $f ${f/DSC/ODSC}; done
To break it down:
for f
This starts a for loop with the variable f, also refered to as $f (the $ means variable)
in
This sets the value of $f to be the output of:
'find . -name '*.JPG'' ;
Which will find and return filenames which adhear to the expression *.JPG (* is used as a wildcard and means any number of any characters) so blah.JPG, DSC0001.JPG, owt.JPG and so on will all be returned.
do mv $f ${f/DSC/ODSC};
Will rename the part of the filename inputted, in this case the variable $f (which is set to what ever find returned), to something else. In this example it is replacing any instance of DSC with ODSC. By preceeding mv with the BSD general command do, mv can be executed from within the running shell process which is this script.
done
This will end the for loop.
I have used various types of loops in PHP and a few other languages and in BASH the following is relevant and very useful to know when structuring a loop:
SYNOPSIS
for start test next body
The for command first invokes the Tcl interpreter to execute start. Then it repeatedly evaluates test as an expression; if the result is non-zero it invokes the Tcl interpreter on body, then invokes the Tcl interpreter on next, then repeats the loop. The command terminates when test evaluates to 0.
Entry for ‘For’ from the BASH Manual
As such, the script I have used can be split into these 4 components of start, test, next and body and indeed I find it easier to understand the process and what each stage of the loop does in this manner.
BASH IT UP.. Now I need to write a script which renames all JPG files in a folder to *0001 sequentially. Or to extract date and time information, order the files oldest to newest and then rename the files in that new order sequentially. That would be tops for sorting out photos from my phone back to date order and have no filename conflicts.
So here it is:
exiftool "-FileName<CreateDate" -d "%Y%m%d_%H%M%S.%%e" /Volumes/Media/K800
And the output is in this format: 20080121_185309.JPG
Using ExifTool by Phil Harvey (you legend) which has very powerful date formatting abilities you can read the EXIF Creation Date field from a file and rename that file with that information, or in this case a formatted version of it. Saves using sed which is great and works very well in a whole directory.