在以前照相用底片的時代,或數位相機初期記憶卡還很小的時候,大家拍照的時候都會很認真的拍,真的好漂亮、好風景才會拍。所以一趟旅遊下來,拍的照片其實不多。但現在不一樣了,隨身的手機動不動就是拍個幾千張的,在整理的時候,其實還蠻困擾的。一方面是要刪除一些重複的、拍壞的、糊掉的,一方面是手機照片全放在一起,要分類也是麻煩。另外是一般手機相片size也都蠻大的,長期下來備份有些困擾。
今天就讓我們來看個之前寫過的Shell Script。它可依據照片EXIF日期訊息,幫照片改名放在依日期建立的目錄內,節省一點整理的時間。這個腳本會運用到 imagemagick 這個套件,所以要使用前記得先裝一下。
自動依JPG EXIF資訊改名歸檔
這個程式會對於指定的檔案,讀取其 EXIF 訊息,取得拍攝日期,並將其改名放入以日期為名稱的目錄。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#!/bin/bash TGT=/home/ubuntu/arch #設定最終輸出的目錄 check_folder() # 檢查目錄是否已存在,不存在則建立 { [ ! -e $TGT/$1 ] && mkdir -p $TGT/$1 } check_file() # 檢查檔案是否存在,不存在傳回0,存在傳回1 { [ ! -e $TGT/$1/$2 ] && return 0 return 1 } IMG=$1 #腳本執行時,需要以圖案檔名為參數 identify -format '%[EXIF:*]' "$IMG" > /tmp/info # 需得檔案的 EXIF 資訊 date=`grep DateTimeDigitized /tmp/info | cut -d= -f 2 | cut -d' ' -f 1 | sed 's/:/-/g'` #從EXIF中取得日期 time=`grep DateTimeDigitized /tmp/info | cut -d= -f 2 | cut -d' ' -f 2 | sed 's/:/-/g'` #從EXIF中取得時間 if [ "$date" = "" ];then # 若沒有 EXIF, 則忽略此檔案 echo "$IMG" exif info not found. ignore exit 1 fi echo $IMG is at $date $time check_folder $date # 創建日期目錄 final=$time check_file $date $final # 檢查新的檔名是否已存在 ret=$? while [ ! $ret -eq 0 ] # 存在的話,在檔尾加上隨機數字再檢查一次 do rand=$RANDOM final=$time-$rand check_file $date $time-$rand ret=$? done convert $IMG -quality 60 $TGT/$date/${date}_${final}.jpg # 將檔案重壓縮,quality 設60減size rm $IMG #mv $IMG $TGT/$date/${date}_${final}.jpg #若不想重壓縮,可直接用mv搬移即可 |
行2: 指定歸檔後,檔案要存放的位置。
行3~5: 定義 check_folder() 函式。檢查指定路徑的目錄是否存在,不存在則創建出來
行7~11: 定義 check_file() 函式。檢查指定路徑的檔名是否存在,不存在返回0,存在返回1。這是用來避免命名時,有拍攝時間完全一樣的狀況,此時命名時會加一個隨機數字。
行12: 腳本會以執行時的第一個參數,做為要處理的檔案。
行13: 利用 ImageMagick 附的檔案資訊辨示程式 Identify, 來取得 EXIF 訊息,並存入 /tmp/info 中。
行14: 利用 grep 工具在剛輸出的 EXIF 訊息中,找到 DateTimeDigitized 這一行 (exif:DateTimeDigitized=2018:02:17 20:42:55)。然後用 cut 以 “=” 和 ” ” 分別做兩次切格取得日期的欄位。最後利用 sed 將 “:” 取代成 “-”
行15: 與取得日期的方法一致,只是取不一樣的欄位(第二次cut)。
行16~19: 若沒取到時間欄位,有可能是這個檔案沒 EXIF 訊息,則不處理此檔案。
行20: 將檔案的日期印到畫面上,檔做顯示進度用。
行21: 利用 check_folder() 來檢查檔案日期的歸檔目錄是否已存在,若不存在會建立。
行23: 利用 check_file() 依據檔案的日期時間,檢查檔案是否已存在。若存在則下面會自動在檔名後面加上一隨機數字。
行24~31: 若確定檔案重複,會隨機在後面加上隨機數字,並再檢查一次,直到沒重複為止。
行32~33: 使用 ImageMagick 主程式 convert, 將檔案重新壓縮,並指定其 quality 為 60。然後將檔案存在到指定的日期資料夾,最後再將舊檔案刪除。
行34: 若不想要做轉檔,可將32~33註解,並將此行的註解移除。
檔案重壓縮
腳本裡面有利用到重壓縮的功能,以 quality 60 為例,可以將 795MB 的照片,減到 273MB。另外將圖檔縮小,也是一個節省空間的方法,imagemagick也有支援縮小的功能。
執行
由於這個腳本是針對個別檔案來操做,所以需要配合指令的下達。這邊我們假設所有的圖檔都是放在 pic/ 這個目錄內。因此,我們可以利用 find 指令,來找出所有JPG檔案,並呼叫腳本 (get_exif.sh) 來處理它。其中 -iname 是指定搜尋檔案不分大小寫, -exec 是找到檔案後,會呼叫後面的程式來處理(找到一次呼叫一次), {} 代表找到的檔名。
1 |
find pic/ -iname "*JPG" -exec ./get_exif.sh {} \; |