シェルスクリプトでファイル名のゼロパディング

やりたいこと

% ls
hoge1.pdf  hoge2.pdf  hoge3.pdf

% ls
hoge001.pdf  hoge002.pdf  hoge003.pdf

としたい。ちなみに環境は Ubuntu 10.04 で、コマンドシェルには zsh を使っています。

ちょー簡単でした

rename コマンド(正しくは file-rename かな?? Debian 系のディストリビューションではデフォルトで入っているみたい)を使います。perl で実装されているので、強力な正規表現を利用することが出来ます。シェルスクリプトで、と謳いながらほぼ perl です…ゴメンナサイ。

やってみよう

まずはテストしてみる。(-n は --no-act の短縮形で、No Action ってことらしいです。)

% rename -n 's/(\d+)/sprintf("%03d",$&)/e' *[0-9]*.pdf
hoge1.pdf renamed as hoge001.pdf
hoge2.pdf renamed as hoge002.pdf
hoge3.pdf renamed as hoge003.pdf

おお!! イケそうです。

ここでメモ

正規表現に注目してみます。

s/(\d+)/sprintf("%03d",$&)/e

s/// の e オプションは置換文字列を式として評価するんだそうです。んで、その置換文字列には

sprintf("%03d",$&)

と、sprintf 関数を使って、正規表現でマッチした文字列*1を整形しています。
書式指定を変更することでゼロの数を調節できます。

% rename -n 's/(\d+)/sprintf("%05d",$&)/e' *[0-9]*.pdf
hoge1.pdf renamed as hoge00001.pdf
hoge2.pdf renamed as hoge00002.pdf
hoge3.pdf renamed as hoge00003.pdf

今回は sprintf で整形するだけですが、もっと複雑なことも出来ると思います。。。perl ワカリマセン><

結果

% rename 's/(\d+)/sprintf("%03d",$&)/e' *[0-9]*.pdf 
% ls
hoge001.pdf  hoge002.pdf  hoge003.pdf

*1:後方参照で取得し、sprintf 関数の引数へ