2010-08-30 34 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