Frage Wie man EXIF-Zeitstempel mit Bash-Skript analysieren kann


Als bash script rookie wären detaillierte Antworten erwünscht. :)

Ich versuche ein Bash-Skript zu schreiben, das JPEG EXIF-Zeitstempel aus dem exiv2 commandline-Dienstprogramm analysiert, was mir eine typische Ausgabe gibt:

Zeitstempel des Bildes: 2010: 07: 27 17:38:52

Gibt es eine Möglichkeit, den Zeitstempel zu analysieren, so dass seine Komponenten wie Jahr, Monat, Tag, Stunde, Minute, Sekunde in die entsprechenden Variablen eingehen?

Würde sed / gawk der richtige Weg sein? Wenn das so ist, wie? Oder ist es auf andere Weise besser?

Auf diese Weise kann ich sie manipulieren oder mischen und anpassen, wie auch immer ich es mag.

Hier ist das Skript, das ich bis jetzt habe:

#!/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"

Vielen Dank!


5
2017-08-30 20:28


Ursprung


Antworten:


Hier ist eine reine Bash-Lösung zum Teilen der Zeitstempel-Spezifikation:

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

Die obige Lösung konvertiert Doppelpunkte in Leerzeichen in der Spezifikation, teilt sie in Whitespaces auf und fügt jedes Element in die jeweilige Variable ein.

Eine Lösung, die awk, sed oder Perl enthält, wäre ähnlich und würde die Zeitstempelaufteilung in einer dieser Sprachen implementieren.

Ich empfehle jedoch die pure bash-Lösung, weil sie schneller ist (sie muss keinen Subprozess erzeugen), und sie hat keine externen Abhängigkeiten. Heutzutage (im Vergleich zu der Bourne Shell in den 1970ern) kann der Großteil der String- und Array-Manipulation in bash selbst durchgeführt werden, ohne Fork, Ex, Tr, Sed, Awk, Perl, Cut usw. ausführen zu müssen.

Mit 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

Mit 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

Mit 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

Mit 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

6
2017-08-30 20:38



Hier ist ein anderer Weg

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

2
2017-08-30 23:57