連番ファイルの数字桁数を揃える

devi
『MIRACLE デビクロくんの恋と魔法』(2014年公開) 嵐の相葉雅紀主演の映画です。
私は元来劇などを見ることがすっごく下手なのですが(下手ってなんだろう)、この映画に関しては完全に失敗しました。相葉雅紀と榮倉奈々が演じる役、光と杏奈が姉弟であると勘違いしてたんです。映画のラストまで。。。姉弟と勘違いしてなければ何の差し支えもなく楽しく最後まで見れたのですが、私はこの姉弟が完全に姉弟だと思ってるから、もういろんなシーン要所要所で、差し支えありありです。映画終わってしばらく、開いた口が塞がらなかったです。映画終わっても、世間が許しても私が許さないとか、いや、いつから世の中はそんな風になってしまったのだろうか、とかいろいろ悩んだのですが、その後、姉でも弟でもないことが分かって、胸をなでおろしたのでした。まあ私の映画の見方が下手だったということで。いつか忘れた頃にもう一回見ようかと思ってます(また姉弟と勘違いするかもしれませんが)。
映画自体は面白いです。大事なものが水たまりに落ちるとか、無関心な人に踏みにじられるとか、頑張ってるのにひどい目にあうデビクロにとりつかれた主人公に感情移入しやすかったです。

劇中に出てきたデビクロ通信は、子供の頃からずっと主人公が続けていましたが、子供の頃に書いてたお絵かきが、いつからかきれいな(A4くらいだろうか)ポスターになってました。絵がうまくなったりコピーを覚えたりして、成長したことで書き方も変わっていったのでしょう。
ところで、運用中にフォーマットの変更、ってのはITの世界でもありますよね。ファイル命名規則、特に数字の桁数。最初は01,02,03,04って番号を使ってたけど、運用しているうちに、足りなくなって001,002,003,004に変えたりする経験等、少なくないと思います。ファイルフォーマットではないですが、IPv4/IPv6の話もこの手の桁数に関連する話ですね。

今回は、数字を含んだファイル名の置換について考えてみます。

例えば1〜10の連番ファイルがあってlsで表示すると、1番の次に10番がきますよね。

~$ touch file{1..10}.txt
~$ ls -1
file1.txt
file10.txt
file2.txt
file3.txt
file4.txt
file5.txt
file6.txt
file7.txt
file8.txt
file9.txt
~$ 

これが気に入らなくて並びを数字順にしたいなら、こんな方法もあるでしょう。

~$ ls | sort -nk1.5
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
file6.txt
file7.txt
file8.txt
file9.txt
file10.txt
~$ 

上記のようにsortコマンドがあれば、ファイル名による多少の不便さは解消できます。
しかしファイル名の桁数さえ最初から合わせてしまえば、sortは使う必要のないコマンドです。

1 → 0001のように、連番ファイルの桁数を合わせてみましょう。

まずは、実験用ファイルfile1.txt〜file100.txtを作成します。

~$ touch file{1..100}.txt
~$ ls file*.txt | wc -l
100
~$ 

番号の桁数はperlで以下の構文を使い置換します。

s/(\d+)/sprintf(“%04d”,$1/e

これをベースにして、mvコマンドでファイル名を置換するスクリプト自体を生成します。

~$ ls | perl -pe 'chop;$a=$_;s/(\d+)/sprintf("%04d",$1)/e;
$_="mv $a $_\n"'
mv file1.txt file0001.txt
mv file10.txt file0010.txt
mv file100.txt file0100.txt
mv file11.txt file0011.txt
mv file12.txt file0012.txt
mv file13.txt file0013.txt
(省略)

mvコマンドのスクリプトを、bashで実行します。

~$ ls | perl -pe 'chop;$a=$_;s/(\d+)/sprintf("%04d",$1)/e;
$_="mv $a $_\n"' | bash
+ mv file1.txt file0001.txt
+ mv file10.txt file0010.txt
+ mv file100.txt file0100.txt
+ mv file11.txt file0011.txt
+ mv file12.txt file0012.txt
+ mv file13.txt file0013.txt
+ mv file14.txt file0014.txt
+ mv file15.txt file0015.txt
+ mv file16.txt file0016.txt
+ mv file17.txt file0017.txt
(省略)
~$ ls
file0001.txt  file0021.txt  file0041.txt  file0061.txt  file0081.txt
file0002.txt  file0022.txt  file0042.txt  file0062.txt  file0082.txt
file0003.txt  file0023.txt  file0043.txt  file0063.txt  file0083.txt
file0004.txt  file0024.txt  file0044.txt  file0064.txt  file0084.txt
file0005.txt  file0025.txt  file0045.txt  file0065.txt  file0085.txt
file0006.txt  file0026.txt  file0046.txt  file0066.txt  file0086.txt
(省略)
~$ 

全部ファイルの数字部分の桁数が4桁になりましたね。

元に戻すのは簡単です。

~$ ls | perl -pe 'chop;$a=$_;s/(\d+)/$1+0/e;
$_="mv $a $_\n"' | bash
+ mv file0001.txt file1.txt
+ mv file0002.txt file2.txt
+ mv file0003.txt file3.txt
+ mv file0004.txt file4.txt
+ mv file0005.txt file5.txt
+ mv file0006.txt file6.txt
+ mv file0007.txt file7.txt
+ mv file0008.txt file8.txt
+ mv file0009.txt file9.txt
+ mv file0010.txt file10.txt
(省略)
~$ ls
file1.txt    file24.txt  file4.txt   file55.txt  file70.txt  file86.txt
file10.txt   file25.txt  file40.txt  file56.txt  file71.txt  file87.txt
file100.txt  file26.txt  file41.txt  file57.txt  file72.txt  file88.txt
file11.txt   file27.txt  file42.txt  file58.txt  file73.txt  file89.txt
file12.txt   file28.txt  file43.txt  file59.txt  file74.txt  file9.txt
file13.txt   file29.txt  file44.txt  file6.txt   file75.txt  file90.txt
file14.txt   file3.txt   file45.txt  file60.txt  file76.txt  file91.txt
~$ 

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA