【ターミナル】加工後のファイルの作成日をオリジナルの作成日に変更する【設定メモ】
表題のシェルスクリプトを作った時の罠のメモ🤤
#!/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 ☺️
母艦から整理済の写真を iPhone へ送って SNS で必要になったら参照するっていう使い方、あるよね?
整理しないままタグだけ付けて検索するとかアルバムで分類してってやってる人も居るだろうけど撮った写真はどんどん溜まるから大抵は整理のために削除したりクラウドや母艦へ移してよく使いそうな物だけ同期で戻して持ち歩くってやるよね☺️
そんな(携帯へ)戻す写真、加工してから戻すものがちらほら有るんでなかろうか?🤤
数が多くなればなる程「いつ撮った写真か」を識別でいるようにしておきたいという人は割と居るんじゃないかな?🤔
そう
加工はしたい
しかし日付けは変えたくない
通常は複製を取って加工、加工して別名保存、のどちらかだと思う。
今回のは後者の話🤤
「別名保存」だとか、非破壊編集で「書き出し」すると日付は「今」になる。
Photoshop に取り込んで編集中のものは .psd で保存して最終出力はまた新たに .jpg .png とかになるよね。
オリジナルは残ってる、加工後も別にある。でも加工後の日付けは加工した日のまま。
それを 携帯電話 へ取り込むと日付順に並べても撮影した日が分からないから分類済フォルダで取り込んだりタグ付けたりってやる事になる。
日付が撮影日になればなぁ
って思うものだよね、 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 の癖とかが有ってなかなか時間取られたわ😞
この処理で必要な要素は
・リストファイルを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 foundが表示されるのね😞
(後からダブルクォーテーション付きの "${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 tool を入れないと使えない
`ls -lT` で年まで取れるけど並びがメチャクチャ
ファイルから入力した文字列のダブルクォーテーションは単純な文字の一部として扱われる
`sed` を使う時、より高度な書式を使いたい場合 -E を忘れずに付ける