【ターミナル】加工後のファイルの作成日をオリジナルの作成日に変更する【設定メモ】

表題のシェルスクリプトを作った時の罠のメモ🤤

#!/bin/bash
LNAME="_list.csv"
DNAME=`pwd`
GREPS='s/\"([^\"]+)\"/\1/'
echo "pwd : ${DNAME}"
if [ -e ${LNAME} ];then
	while read LINE || [ -n "${LINE}" ] ;do
        DDATA=`echo ${LINE} | cut -d ',' -f 1 | sed -E ${GREPS}`
		FDATA=`echo ${LINE} | cut -d ',' -f 2 | sed -E ${GREPS}`
        if [ -e "${FDATA}" ];then
			echo "setfile : ${DDATA} , ${FDATA}"
			setfile -d "${DDATA}" "${FDATA}"
			setfile -m "${DDATA}" "${FDATA}"
		else
			echo "not found : ${FDATA}"
		fi
	done < ${LNAME}
else
	echo "not found : ${LNAME}"
fi

→ ls -lUT
→ /^.+ [ ]?(\d+)[ ]+(\d+)[ ]+(\d\d\:\d\d\:\d\d)[ ]+(\d{4})[ ]+(.+)$/"$1\/$2\/$4 $3","$5"/
→ /\"(\d\d[bnhal])\.([^.]+).(iidx)(\d\d)(.arena)?.f.0.jpg\"/"BMGA.$3.$4.$1.$2.f.0$5.png"/


事の起こり

携帯使ってる?Android?iPhone?
ウチは iPhone ☺️

母艦Macから整理済の写真を iPhone へ送って SNS で必要になったら参照するっていう使い方、あるよね?
整理しないままタグだけ付けて検索するとかアルバムで分類してってやってる人も居るだろうけど撮った写真はどんどん溜まるから大抵は整理のために削除したりクラウドや母艦パソコンへ移してよく使いそうな物だけ同期で戻して持ち歩くってやるよね☺️

そんな(携帯へ)戻す写真、加工してから戻すものがちらほら有るんでなかろうか?🤤
数が多くなればなる程「いつ撮った写真か」を識別でいるようにしておきたいという人は割と居るんじゃないかな?🤔

そう

加工はしたい
しかし日付けは変えたくない

通常は複製を取って加工、加工して別名保存、のどちらかだと思う。
今回のは後者の話🤤
「別名保存」だとか、非破壊編集で「書き出し」すると日付は「今」になる。
Photoshop に取り込んで編集中のものは .psd で保存して最終出力はまた新たに .jpg .png とかになるよね。
オリジナルは残ってる、加工後も別にある。でも加工後の日付けは加工した日のまま。
それを  携帯電話iPhoneとかAndroid へ取り込むと日付順に並べても撮影した日が分からないから分類済フォルダで取り込んだりタグEXIF付けたりってやる事になる。

日付が撮影日になればなぁ

って思うものだよね、 PC から取り込む写真が多い程🤤

PC 使ってるならね、大抵はファイルの日付けはイジれるようになってるのよね。
だからそれをバッチ処理できるものを作ろうってなったわけ。
普通は1回やったらそれまでなんだけど、自分の場合は「再出力」する可能性が有り、都度変更処理が要ると判っていたので作る事に🤪


撮影日を取得

撮影したファイルが残っているのが大前提🤤

$ ls -lUT
$ ls -lUT
total 33816
drwxr-xr-x  11 user  staff      374  4  9 17:05:39 2021 ./
drwxr-xr-x   4 user  staff      136  4  9 17:08:16 2021 ../
-rw-------@  1 user  staff   194589  6 30 20:51:56 2014 01h.GAMBOL.iidx21.f.0.jpg
-rw-------@  1 user  staff   193948  9 20 20:06:35 2014 01h.GAMBOL.iidx22.f.0.jpg
-rw-------@  1 user  staff  1727300 10 24 17:45:57 2016 01h.GAMBOL.iidx23.f.0.jpg
-rw-------@  1 user  staff  1655568 10 31 17:43:08 2016 01h.GAMBOL.iidx24.f.0.jpg
-rw-------@  1 user  staff  1698881 12 25 19:12:04 2017 01h.GAMBOL.iidx25.f.0.jpg
-rw-------@  1 user  staff  2965512  8 31 19:14:42 2019 01h.GAMBOL.iidx26.arena.f.0.jpg
-rw-------@  1 user  staff  2830069 12 15 16:24:51 2018 01h.GAMBOL.iidx26.f.0.jpg
-rw-------@  1 user  staff  2874640  2 26 20:56:59 2020 02h.GAMBOL.iidx27.f.0.jpg
-rw-------@  1 user  staff  2953097 12  2 18:25:25 2020 02h.GAMBOL.iidx28.f.0.jpg

大抵の記事では `ls -lT` と出てくるかな🤤
この文字列をテキスト保存して加工するのだわさ☺️


日付タイムスタンプとファイル名

ls で取得した文字列を日付タイムスタンプとファイル名に加工🤤
ウチの環境では mi.app の正規表現による置換でやった☺️

検索:^.+ [ ]?(\d+)[ ]+(\d+)[ ]+(\d\d\:\d\d\:\d\d)[ ]+(\d{4})[ ]+(.+)$
置換:"$1/$2/$4 $3","$5"
_list.csv

"6/30/2014 20:51:56","01h.GAMBOL.iidx21.f.0.jpg"
"9/20/2014 20:06:35","01h.GAMBOL.iidx22.f.0.jpg"
"10/24/2016 17:45:57","01h.GAMBOL.iidx23.f.0.jpg"
"10/31/2016 17:43:08","01h.GAMBOL.iidx24.f.0.jpg"
"12/25/2017 19:12:04","01h.GAMBOL.iidx25.f.0.jpg"
"8/31/2019 19:14:42","01h.GAMBOL.iidx26.arena.f.0.jpg"
"12/15/2018 16:24:51","01h.GAMBOL.iidx26.f.0.jpg"
"2/26/2020 20:56:59","02h.GAMBOL.iidx27.f.0.jpg"
"12/2/2020 18:25:25","02h.GAMBOL.iidx28.f.0.jpg"

このままだとファイル名がまだ古いままなので加工後の名前に変換☺️
なんで一発でやらないかっていうと他のファイル名パターンが有るから🤪

最初はダブルクォーテーション無かったんだけどシェル処理の都合で有ったほうが良いと判りダブルクォーテーション付きに変更🤤

検索:"(\d\d[bnhal])\.([^.]+).(iidx)(\d\d)(.arena)?.f.0.jpg"
置換:"BMGA.$3.$4.$1.$2.f.0$5.png"
_list.csv

"6/30/2014 20:51:56","BMGA.iidx.21.01h.GAMBOL.f.0.png"
"9/20/2014 20:06:35","BMGA.iidx.22.01h.GAMBOL.f.0.png"
"10/24/2016 17:45:57","BMGA.iidx.23.01h.GAMBOL.f.0.png"
"10/31/2016 17:43:08","BMGA.iidx.24.01h.GAMBOL.f.0.png"
"12/25/2017 19:12:04","BMGA.iidx.25.01h.GAMBOL.f.0.png"
"8/31/2019 19:14:42","BMGA.iidx.26.01h.GAMBOL.f.0.arena.png"
"12/15/2018 16:24:51","BMGA.iidx.26.01h.GAMBOL.f.0.png"
"2/26/2020 20:56:59","BMGA.iidx.27.02h.GAMBOL.f.0.png"
"12/2/2020 18:25:25","BMGA.iidx.28.02h.GAMBOL.f.0.png"

"(iidx)(\d\d)" は "(iidx)(\d+)" でも良いかな?🤔


バッチファイル

準備は順調だったけどここで罠が発生🤪
結構複雑な事をしていたので仕方のない事ではあると思うけど判ってなかった bash の癖とかが有ってなかなか時間取られたわ😞

この処理で必要な要素は

リストファイル.csvを1行ずつ取り込む
・取り込んだ行を日付とファイル名で取り出す
・そのファイルが有れば setfile で日付を作成日として変更する

リストファイルの読み込みは

bash while read line

で引くとやり方が色々出てくる☺️
今回参照したのは「改行で終わってなくても処理する」という旨の記事🤔

BASHのwhile readで最終行が処理されない問題の解決方法
https://qiita.com/Ets/items/a7fa24b138b8ee883dac

先人の記録はとても役に立つ🤤

一番問題が多かったのは .csv の1行を切り分ける部分🙄
最初は↓の状態だったのよね

DDATA=`echo ${LINE} | cut -d ',' -f 1`
FDATA=`echo ${LINE} | cut -d ',' -f 2`

なんかこれだと `if [ -e ${FDATA} ]` が true にならないらしく、ずっと not foundelseの処理が表示されるのね😞
(後からダブルクォーテーション付きの "${FDATA}" になった)

抜き出した文字がダブルクォーテーションで囲まれてるからそのままイケるって思ってたんだけどどうやら↓の様なカラクリらしい事が変数の中身を調べていて判明🙄

FDATA=`echo ${LINE} | cut -d ',' -f 2`    # "BMGA.iidx.21.01h.GAMBOL.f.0.png"
FDATA="BMGA.iidx.21.01h.GAMBOL.f.0.png"   # BMGA.iidx.21.01h.GAMBOL.f.0.png

そう、つまり

ダブルクォーテーション付きのファイル名として
`test -e` していた
🙄🙄🙄

で、この後ダブルクォーテーションを一旦剥ぎ取る方法を調べて変数の書き方${変数/検索文字列/置換文字列}を試したりとか、結局 sed に行き着いたとか、自分が使う正規表現は拡張なので -E オプションが付いてないと動作しないとか有ってすったもんだしたけど冒頭のスクリプトに落ち着いた🤤


罠まとめ

`setfile` は developer toolXcode を入れないと使えない
`ls -lT` で年まで取れるけど並びがメチャクチャ
ファイルから入力した文字列のダブルクォーテーションは単純な文字の一部展開されないシングルクォーテーションで括ってある様な状態として扱われる
`sed` を使う時、より高度な書式を使いたい場合 -E を忘れずに付ける


画像1


この記事が気に入ったらサポートをしてみませんか?