« 2012年1月1日 - 2012年1月7日 | トップページ | 2012年2月12日 - 2012年2月18日 »

2012年2月 9日 (木)

cp_with_prefix.pl: ディレクトリ平坦化機能付きコピー

ハードのメディアプレイヤーで画像をランダムに閲覧したい。私が持っているメディアプレイヤーに限らず専用ハードのものはたいていそうだが、PC などのソフトではあった、zip にまとめられたものを見るようなことはできず、また、ディレクトリの構造を奥へ奥へと "recursive" に辿って見るような機能もない。フォルダ内のランダム再生はある。

そこでディレクトリ構造を平坦化(flattening)してコピーするような Perl スクリプトを書いた。

はじめはソースと同じファイル名(ベース名)で一つのディレクトリにコピーしたとき重複を避けるため、手動で接頭辞(prefix)を付けられるようにすれば十分かと考えたが、使うと面倒くさいので、-F オプションによって、ファイル名にディレクトリが含まれているとき、そのディレクトリ名を prefix とする機能も作った。

例えば、

$ perl cp_with_prefix.pl --prefix=p_ a/b/c.jpg d


…としたときは、d/p_c.jpg というファイルができる。

$ perl cp_with_prefix.pl -F a/b/c.jpg d


…としたときは d/a_b_c.jpg というファイルができる。

Cygwin の mv や cp の実装を参考に、xargs といっしょに使いやすいよう -t (ターゲットディレクトリ)オプションを用意した。

例えば次のように使う。

$ find dir1 dir2 -name '*' -print0 | xargs -0 perl cp_with_prefix.pl -F -t dir3


こうすると、dir1 や dir2 の下にあるファイルがリカーシブに dir3 の下にファイル名の重複が(ほぼ)なくなるようにコピーされる。

なお、私の最初に書いた目的にそった上で高速化するため、同じファイル名があったときはコピーせずスキップする。ちゃんと上書き(overwrite)して欲しいときは -f (force)オプションを付ければよい。スキップしている表示がうっとうしいなら、-q (quiet)オプションを付ければよい。目的がただの rename に近いため、コピーしたあとの日付けはソースと変わらないようにしている。

ファイル名とコンソールの文字エンコーディングについては、ソースの以下の部分をいじって欲しい。本当は、ロケールとかを使ってコーディングできれば美しいのだが、これまでの私の経験から言うと、オプションで指定してもらうか、今回のようにスクリプトをいじってもらったほうが話が早い。現在、 Cygwin の 1.7 系列の場合、ファイルシステムのエンコーディングが cp932 (Windows 用の Shift JIS コード)であっても、utf8 で処理される。昔の Cygwin であれば、utf8 の部分を、ファイル名では cp932 にコンソールでは euc-jp にすると、うまくいくかもしれない。

our $FILENAME_ENCODER = Encode::find_encoding('utf8') or die;
our $CONSOLE_ENCODER = Encode::find_encoding('utf8') or die;



配布物


これは、とても簡単なプログラムなので、数式のようにパブリックドメインなものとして扱っていただいてよい。こんなプログラマなら誰でも作れそうなものをプログラムできる人しか使えないであろう Perl スクリプトで公開する意義はないかもしれないが、こんな簡単な機能がググっても見つからないのも変なので公開することにした。

関連


スクリプト自体はパッと見つからないが、シェルで同じような機能を求めてる人はいそうだった。Windows なら高機能なリネームソフトはいろいろある。 iTunes とかもそういう機能がありそうだが、このような機能だけが欲しくて使っているとかありうるんだろうか?

Flexible Renamer》。Windows 用のリネームソフトの例。
更新: 2012-02-09,2012-02-11
初公開: 2012年02月09日 22:26:18
最新版: 2012年02月11日 19:10:51

2012-02-09 22:26:15 (JST) in Cygwin, JRF 作成ソフトウェア, Perl | | コメント (2) | トラックバック (0)