1〜12月の各月のデータを格納する目的で、ゼロパディングされた数値でディレクトリを作成したい。楽をしたいので、まずはゼロパディングされた連番を出力する方法を探ってみた。
シェルスクリプト(/bin/sh)の場合
seq(1)には、ゼロパディングして数値の幅を均等化するオプション -w がある。
seq -w 1 12
01 02 03 04 05 06 07 08 09 10 11 12
ところで、任意の桁数にゼロパディングしたい場合はどうか? 例えば2桁ではなく3桁にゼロパディングしたいならどうか?
GNU coreutilsの場合は、次のように開始値ないし終了値を予めゼロパディングしておけばよいようだ。
seq -w 001 12 seq -w 1 012
001 002 003 004 005 006 007 008 009 010 011 012
しかしこの方法は、Mac OS Xでは使えないようだ(他の*BSDでも使えないかもしれない)。
恐らく、多少は移植性を気にするのなら、オプション -f で明示的に出力フォーマットを指定するべきだろう。
seq -f %03g 1 12
カレントディレクトリに連番ディレクトリを作る分には、seq(1)でも十分だ。
mkdir `seq -w 1 12`
bashの場合
bashならブレース展開が使える。
echo {01..12}
01 02 03 04 05 06 07 08 09 10 11 12
予め「01」とパディングしておく必要があるので注意。
3桁で出力したい場合は、次の通り。
echo {001..12} echo {1..012}
001 002 003 004 005 006 007 008 009 010 011 012
seq(1)ではなくbashを使う利点は、例えば次のようなケースだ。
mkdir -p foo/{01..12}
この場合、カレントディレクトリにfooというディレクトリが生成された上で、fooの直下に連番ディレクトリが生成される。
echo(1)で展開結果を見ると、その理由が分かる。
$ echo mkdir -p foo/{01..12} mkdir -p foo/01 foo/02 foo/03 foo/04 foo/05 foo/06 foo/07 foo/08 foo/09 foo/10 foo/11 foo/12
「foo/」付きで展開されている!
残念ながらseq(1)ではそうはいかない。
mkdir -p hoge/`seq -w 1 12`
echo(1)で展開結果を見ると、非常に残念な感じになっている。
$ echo mkdir -p hoge/`seq -w 1 12` mkdir -p hoge/01 02 03 04 05 06 07 08 09 10 11 12
seq(1)で同じことを実現したい場合、sed(1)などでseq(1)の出力を加工するぐらいしか方法が思いつかない。
$ echo mkdir -p `seq -w 1 12 | sed 's!^!foo/!'` mkdir -p foo/01 foo/02 foo/03 foo/04 foo/05 foo/06 foo/07 foo/08 foo/09 foo/10 foo/11 foo/12
PowerShell 2.0の場合
PowerShellの範囲演算子は、あくまでも「連続する整数の配列」を返すので、そのままではゼロパディングできない。
そこでフォーマット演算子 -f を併用する。
1..12 | %{ "{0:d2}" -f $_ }
01 02 03 04 05 06 07 08 09 10 11 12
3桁で出力したい場合は、次の通り。
1..12 | %{ "{0:d3}" -f $_ }
001 002 003 004 005 006 007 008 009 010 011 012
カレントフォルダに連番フォルダを作るなら、こんな感じ。
1..12 | %{ "{0:d2}" -f $_ } | %{ New-Item $_ -ItemType directory }
New-Itemの代わりにmkdir(md)を使ってもよいだろう。
もしフォルダfooを作成した上で、その中に連番フォルダを作るなら、seq(1)の時と同様に出力されるフォルダ名を個別に加工する必要がある。
1..12 | %{ "foo\{0:d2}" -f $_ } | %{ New-Item $_ -ItemType directory }
バッチファイルの場合
悪いことは言わないから、PowerShellを使いなさい。それかCygwinかMSYSあたりをインストールして、Unixツール群を入手して使いなさい。
……単なる連番フォルダなら作れるのだが。
for /L %I in (1,1,12) do @mkdir %I