日次アーカイブ: 2014年11月30日

ニチアサですね、おはようございます。 @nullpopopo でございます。雑誌に掲載する写真を選んでいるのですが、いただいた写真はiPhoneで撮影したものとデジカメで撮影したものが混在していました。前者はタイムスタンプがそのままファイル名になったYYYY-MM-DD_HH.MM.SS.jpg、後者はDSCNNNNN.JPGという連番ファイル名です(蛇足ですがAndroid携帯のファイル名ですとDSC_NNNN.JPGなので、今回取り上げるワンライナーで応用が効くかと)。

これをパソコン(Fedora20)に取り込んで時系列で順番に見たいのですが、コマンドラインですと「ls --full-time」で時系列に並べ替えることができます。しかしnautilusでサムネイル表示するのに、1回1回更新日時順にソートするのも面倒です。じゃあデジカメ画像のほうをリネームしてしまえ!ということで以下のワンライナーを実行。

ls --full-time DSC* | awk '{print "mv",$NF,$6"_"$7"_"$NF}' | sed -e 's/.000000000//g;s/:/./g;s/JPG$/jpg/g' | sh

lsコマンドに--full-timeオプションをつけたときの表示はこんな感じです。

$ ls --full-time DSC* | head -n 1
-rw-r--r-- 1 hamada hamada 1748093 2014-11-04 09:13:48.000000000 +0900 DSC04071.JPG

この出力結果をawkに食わせるのですが、もうここでmvコマンドを表示させてしまいます。実行結果は以下の通り。

$ ls --full-time DSC* | head -n 1 | awk '{print "mv",$NF,$6"_"$7"_"$NF}'
mv DSC04071.JPG 2014-11-04_09:13:48.000000000_DSC04071.JPG

しかしこれだけですと、単に実行したいコマンドが標準出力に表示されるだけでなく、日付のフォーマットもiPhoneのファイル名と異なります。また、拡張子が大文字のままです。なので、リネーム後のファイル名をsedで整形してしまいましょう。なお、元のファイル名(DSCNNNNN)は、iPhoneのファイル名と衝突しないよう、また、元々がデジカメのファイル名だったことがlsだけでわかるように残すこととします。

$ ls --full-time DSC* | head -n 1 | awk '{print "mv",$NF,$6"_"$7"_"$NF}' | sed -e 's/.000000000//g;s/:/./g;s/JPG$/jpg/g'
mv DSC04071.JPG 2014-11-04_09.13.48_DSC04071.jpg

いい感じですね。あとはパイプでshコマンドに渡してあげればリネームできてしまいます。ワンライナーやシェルスクリプトの実行結果が予想できないうちは、このように標準出力に表示させておいて、最後に一気にshに渡してしまうクセをつけると、何度も確認しながらコマンドを組み立てることができます。また、複数ファイルのリネームなどをforで回すより実行結果が速くなりますのでオススメですよ。ね、簡単でしょう?