繰り返し似たような編集を行う場合、サクラエディタのマクロ機能などを使ったりしますが、 もうちょっと複雑な編集がしたい時など、javascriptで書けたりすると便利ですよね(正規表現や条件分岐を使いたい、とか)。

そんなとき、node.jsを使うと割と簡単に実現できそう。

var fs = require('fs');
exports.do = function(params, edit){
    var params = params || {};
    var bufSize = params.bufferSize || 512;
    var tempPath = params.path + ".tmp";
    var rs = fs.createReadStream(params.path, { highWaterMark:bufSize });
    var ws = fs.createWriteStream(tempPath);

    var lbuf = '';
    rs.on('data', function(data) {
        var str = data.toString();
        if (0 < str.indexOf("\n")) {
            lbuf += str;
            var line = lbuf.split("\n");
            for (var i = 0; i < line.length - 1; i++) {
                ws.write(edit(line[i]) + "\n");
            }
            lbuf = line[line.length - 1];
        }
        else {
            lbuf += str;
        }
    }).on('end', function() {
        ws.write(edit(lbuf));
        fs.unlink(params.path, function() {
            fs.rename(tempPath, params.path);
        });
    });
};

上記スクリプトを edit_file.js として保存。

var edit_file = require('./edit_file');

var i = 0;
edit_file.do({ path: "test.txt" }, function(line){
	return (++i) + ": " + line;
});

実際の編集部分を edit.js として保存。

node edit.jsでtest.txtが書き換わります。

edit_file.do の第二引数に行毎の処理を書いて結果をreturnする感じ。 (※上記の例では各行の先頭に行番号が入ります)

node.js現時点で最新のv0.12.4では、Stream3が使えるのできっともっと良いコードで書けるんでしょうけど、とりあえずやりたいことができたからこれでいいや、って感じッス。

node.jsももっと使えるようになりたいなあ。

参考:

http://surendergg.blog.fc2.com/blog-entry-7.html