2010-08-30 19 views
5

Là một tân binh kịch bản bashie, các câu trả lời chi tiết sẽ được đánh giá cao. :)Cách phân tích tem thời gian EXIF ​​với tập lệnh Bash

Tôi cố gắng để viết một kịch bản bash rằng phân tích JPEG EXIF ​​tem thời gian đầu ra từ các tiện ích exiv2 commmandline, mà mang lại cho tôi kết quả điển hình như:

Hình ảnh dấu thời gian: 2010: 07: 27 17: 38:52

Có cách nào phân tích dấu thời gian sao cho thành phần của nó, như năm, tháng, ngày, giờ, phút, giây, đi vào các biến tương ứng?

Có thể sử dụng lối đi ngắn ngủi không? Nếu vậy, làm thế nào? Hoặc là một số cách khác tốt hơn?

Bằng cách này, tôi có thể thao tác hoặc trộn và kết hợp chúng theo cách tôi muốn.

Đây là kịch bản tôi đã có cho đến nay:

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

Cảm ơn!

Trả lời

6

Dưới đây là một giải pháp bash tinh khiết cho tách dòng đặc điểm kỹ thuật timestamp:

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 

Các giải pháp trên chuyển đổi dấu hai chấm để khoảng trống trong các đặc điểm kỹ thuật, chia tách nó trên khoảng trắng, và đặt mỗi mục trong biến tương ứng.

Một giải pháp liên quan đến awk, sed hoặc Perl sẽ tương tự, triển khai phân tách dấu thời gian bằng một trong các ngôn ngữ đó.

Tôi khuyên bạn nên sử dụng giải pháp bash thuần túy vì nó nhanh hơn (không phải sinh ra một tiến trình con) và không có phụ thuộc bên ngoài. Ngày nay (so với Bourne Shell trong những năm 1970) hầu hết các thao tác chuỗi và mảng có thể được thực hiện trong chính bash, mà không cần phải ngã ba và exec expr, tr, sed, awk, perl, cắt, v.v.

Với 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 

Với 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 

Với 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 

Với 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

Đó là tuyệt vời. CẢM ƠN BẠN rất nhiều cho câu trả lời nhanh chóng và rất chi tiết !!! :) – hpy

+0

Đó là một câu trả lời thực sự tuyệt vời. – dawg

+1

Đây là phiên bản đơn giản của 'split_timestamp':' split_timestamp() {local S = ($ {1 //: /}); echo $ {S [@]: 2}; } ' –

2

Dưới đây là một cách khác để

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

Bạn không cần [và] trong IFS. Làm cho nó trở thành một hàm, và biến IFS thành một biến cục bộ. – pts

Các vấn đề liên quan