Unicodeなファイル名を操作するのに最適なスクリプト言語(Windows限定)

やりたいことは、フォルダの中にある全てのファイルを圧縮するとか、リネームするとか、そういう簡単な作業。こういったことを、WindowsUnicodeの(CP932の範囲にない)文字を含むファイルに対して行いたい。

少なくとも今のところは、RubyとかPerlではそういったファイルを普通に扱うことができない*1Python 3.0 では扱えるという情報も聞いて試してみたものの、以下のような結果になったりして……

>>> import os
>>> os.listdir('.')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python30\lib\io.py", line 1491, in write
    b = encoder.encode(s)
UnicodeEncodeError: 'cp932' codec can't encode character '\u9dd7' in position 14: illegal multibyte sequence

取るのは簡単だけど、コンソールの文字コードがcp932なのでそのままでは出力できなかったりする。コマンドプロンプトの dir コマンドのようにそのまま表示したいんだけど……。ともかく、Pythonをロクに知らないということもあって私には少々扱いづらい。

ということで、やっぱりUnix文化圏由来のツールではなく、WindowsならWindowsに用意されているものでやった方が良いという結論になった。それが、JScript

たとえば、あるフォルダの中のファイル全てに ".bak" をつける場合は以下のようになる。

var fso = WScript.CreateObject("Scripting.FileSystemObject");
var shell = WScript.CreateObject("WScript.Shell");

var folder = fso.GetFolder("C:\\tmp");
var files = folder.Files;

for(var en = new Enumerator(files); !en.atEnd(); en.moveNext()) {
    var name = en.item();
    WScript.Echo("moving " + name + " ...");
    fso.MoveFile(name, name + ".bak");
}

こういうスクリプトファイルを適当にファイルに保存したら、コマンドプロンプト

C:\tmp> cscript test.js

のように cscriptコマンドで実行できる。Unicodeのファイル名でも問題なく操作できるし、WScript.Echo の出力もPythonのようにエラーにならず綺麗に表示される。おまけに最近のWindowsなら何のインストール作業も不要。

VBはよくわからないし、バッチは貧弱すぎるので基本JavaScriptJScriptが私にとっては最適だった。

*1:Perlでは Read and write Unicode filenames on Win32 Perl の方法で扱えるみたいだけど面倒…