【问题标题】:How to parse of EXIF time stamps with Bash script如何使用 Bash 脚本解析 EXIF 时间戳
【发布时间】:2011-04-05 23:05:47
【问题描述】:

作为一个 bash 脚本新手,我们将不胜感激。 :)

我正在尝试编写一个 bash 脚本来解析从 exiv2 命令行实用程序输出的 JPEG EXIF 时间戳,这给了我典型的输出,例如:

图片时间戳: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"

谢谢!

【问题讨论】:

    标签: parsing bash time timestamp


    【解决方案1】:

    这是一个用于拆分时间戳规范行的纯 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 解决方案,因为它更快(不必产生子进程),并且没有外部依赖项。如今(与 1970 年代的 Bourne Shell 相比)大多数字符串和数组操作都可以在 bash 本身中完成,而无需 fork 和 exec expr、tr、sed、awk、perl、cut 等。

    使用 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
    

    带 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
    

    【讨论】:

    • 这是一个非常好的答案。
    • 这里是split_timestamp的更简单版本:split_timestamp () { local S=(${1//:/ }); echo ${S[@]:2}; }
    【解决方案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
    

    【讨论】:

    • IFS 中不需要 [ 和 ]。把它变成一个函数,把 IFS 变成一个局部变量。
    猜你喜欢
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2010-12-06
    • 2021-06-30
    相关资源
    最近更新 更多