As a bash script rookie, detailed answers would be appreciated. :)
I am trying to write a bash script that parses JPEG EXIF time stamps output from the exiv2 commmandline utility, which gives me typical output like:
Image timestamp : 2010:07:27 17:38:52
Is there a way to parse the time stamp so that its components, like year, month, day, hour, minute, second, go into respective variables?
Would sed/gawk be the way to go? If so, how? Or is some other way better?
This way, I can manipulate or mix and match them however I like.
Here is the script I've got so far:
#!/bin/bash
COUNT=0
SKIPPED=0
FILES=0 # number of files encountered
# declare variables for time stamp
YEAR=0
MONTH=0
DAY=0
HOUR=0
MINUTE=0
SECOND=0
for CURRENT_FILE in * # a for loop to go through all files in current directory
do
if [ -f "$CURRENT_FILE" ] # see if CURRENT_FILE is a file
then
FILETYPE=$(file -b --mime-type "$CURRENT_FILE") # get file type
if [[ $FILETYPE == image/jpeg ]] # see if CURRENT_FILE's mime is image/jpeg
then
((COUNT++))
echo "Processing file $COUNT: $CURRENT_FILE"
exiv2 "$CURRENT_FILE" | grep timestamp >> list
else
((SKIPPED++))
echo "Skipping file $CURRENT_FILE....."
fi
((FILES++))
fi
done
echo "Encountered $FILES files"
echo "Processed $COUNT files"
echo "Skipped $SKIPPED files"
Thanks!
Here is a pure bash solution for splitting the timestamp specification line:
SPEC='Image timestamp : 2010:07:27 17:38:52'
read X X YEAR MONTH DAY HOUR MINUTE SECOND <<<${SPEC//:/ }
echo $YEAR
echo $MONTH
echo $DAY
echo $HOUR
echo $MINUTE
echo $SECOND
The solution above converts colons to spaces in the specification, splits it on whitespace, and puts each item in the respective variable.
A solution involving awk, sed or Perl would be similar, implementing the timestamp splitting in one of those languages.
I recommend the pure bash solution though, because it's faster (doesn't have to spawn a subprocess), and it doesn't have external dependencies. Nowadays (compared to the Bourne Shell in the 1970s) most of the string and array manipulation can be done in bash itself, without having to fork and exec expr, tr, sed, awk, perl, cut etc.
With Perl:
SPEC='Image timestamp : 2010:07:27 17:38:52'
read X X YEAR MONTH DAY HOUR MINUTE SECOND <<<$(perl -pe 'y@:@ @' <<<$SPEC)
echo $YEAR
echo $MONTH
echo $DAY
echo $HOUR
echo $MINUTE
echo $SECOND
With tr:
SPEC='Image timestamp : 2010:07:27 17:38:52'
read X X YEAR MONTH DAY HOUR MINUTE SECOND <<<$(tr : ' ' <<<$SPEC)
echo $YEAR
echo $MONTH
echo $DAY
echo $HOUR
echo $MINUTE
echo $SECOND
With sed:
SPEC='Image timestamp : 2010:07:27 17:38:52'
read X X YEAR MONTH DAY HOUR MINUTE SECOND <<<$(sed 's/:/ /g' <<<$SPEC)
echo $YEAR
echo $MONTH
echo $DAY
echo $HOUR
echo $MINUTE
echo $SECOND
With AWK:
SPEC='Image timestamp : 2010:07:27 17:38:52'
read X X YEAR MONTH DAY HOUR MINUTE SECOND <<<$(awk '{gsub(/:/," ");print}' <<<$SPEC)
echo $YEAR
echo $MONTH
echo $DAY
echo $HOUR
echo $MINUTE
echo $SECOND
Here's another way
s="Image timestamp : 2010:07:27 17:38:52"
$ IFS="[: ]"
$ set -- $s
$ echo $3
2010
$ echo $4
07
$ echo $5
27
$ echo $6
17
$ echo $7
38
$ echo $8
52
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With