2010-08-30 55 views
5

作爲bash腳本菜鳥,詳細的答案將不勝感激。 :)如何使用Bash腳本解析EXIF時間戳

我嘗試寫分析從exiv2 commmandline工具,這給了我典型的輸出如JPEG EXIF時間戳輸出bash腳本:

圖片時間戳:2010:07:27 17: 38:52

有沒有辦法解析時間戳,以便其組件像年,月,日,小時,分鐘,秒進入各自的變量?

會sed/gawk成爲路要走嗎?如果是這樣,怎麼樣?還是有其他更好的方法?

這樣,我可以操縱或混合他們,但我喜歡。

這裏是腳本到目前爲止我有:

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

謝謝!

回答

6

這裏是分割時間戳規範線純bash的溶液:

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 

在溶液上方轉換冒號爲空格在本說明書中,將其分解的空白,並提出在各可變每個項目。

涉及到awk,sed或perl的解決方案是類似的,實現了其中一種語言的時間戳分割。

儘管我推薦純bash解決方案,因爲它速度更快(不必產生子過程),並且它沒有外部依賴關係。現在(與20世紀70年代的Bourne Shell相比)大部分字符串和數組操作都可以在bash中完成,而不必fork和exec expr,tr,sed,awk,perl,cut等。

With Perl :

SPEC='Image timestamp : 2010:07:27 17:38:52' 
read X X YEAR MONTH DAY HOUR MINUTE SECOND <<<$(perl -pe '[email protected]:@ @' <<<$SPEC) 
echo $YEAR 
echo $MONTH 
echo $DAY 
echo $HOUR 
echo $MINUTE 
echo $SECOND 

隨着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 

隨着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 

隨着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 
+0

這是驚人的。非常感謝您的快速和非常詳細的答案! :) – hpy 2010-08-30 21:03:57

+0

這是一個非常好的答案。 – dawg 2010-08-31 00:00:40

+1

下面是'split_timestamp'的簡單版本:'split_timestamp(){local S =($ {1 //:/}); echo $ {S [@]:2}; }' – 2010-08-31 02:24:14

2

這裏的另一種方式

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 
+0

你不需要IFS中的[和]。讓它成爲一個函數,並使IFS成爲局部變量。 – pts 2010-08-31 12:18:40