コモノExtendScript100本ノック

超初心者のDTPオペレーターが週にひとつスクリプトを書くブログ

051.フォルダ・ファイルを一括リネーム

書いたコード

//@targetengine "renameFiles"

var log =[];
var folderObj = Folder.selectDialog("フォルダを選択してください");
if (folderObj) {
    var fileList = folderObj.getFiles();
} else {
    alert("キャンセルしました");
    exit();
}

// ファイル名を取得
var fLen = fileList.length;
var fNames = [];
for (var i = 0; i < fLen; i++) {
    fNames.push(fileList[i].name);
}
var fNamesStr = fNames.join("\n");

// ウィンドウ表示
var myDlg = new Window("palette", "一括リネーム");
var main = myDlg.add("group {alignChildren: 'left', orientation: 'row'}");
var leftColumn = main.add("panel", undefined, "変更前");
var beforeName = leftColumn.add("edittext", [0, 0, 300, 350], decodeURI(fNamesStr), {
    multiline: true
});
var rightColumn = main.add("panel", undefined, "変更後");
var afterName = rightColumn.add("edittext", [0, 0, 300, 350], "", {
    multiline: true
});
var start = myDlg.add("button", undefined, "実行");
myDlg.show();

// リネーム
start.onClick = function() {
    var beforeNameArr = beforeName.text.split("\n");
    var beforeNameLen = beforeNameArr.length;
    var afterNameArr = decodeURI(afterName.text).split("\n");
    var afterNameLen = afterNameArr.length;
    if (chkDuplicates(afterNameArr).length > 0) {
        alert("ファイル名が重複しています");
        exit();
    }
    if (beforeNameLen !== afterNameLen) {
        alert("変更前後の数が異なります");
        exit();
    }
    for (var i = 0; i < afterNameLen; i++) {
        if (!existInArr(fNames, encodeURI(beforeNameArr[i]))) {
            alert("該当のファイルが見つかりません");
            exit();
        }
    }
    // 変更していく順番によってはファイル名が重複する可能性があるので一旦仮の名前にリネーム
    for (var i = 0; i < beforeNameLen; i++) {
        var fId = getIdInArr(fNames, encodeURI(beforeNameArr[i]));
        fileList[fId].rename("〓" + fileList[fId].name); // ファイル名にゲタを使用しない想定
    }

    // リネーム本番
    for (var i = 0; i < afterNameLen; i++) {
        var fId = getIdInArr(fNames, encodeURI(beforeNameArr[i]));
        log.push(decodeURI(fileList[fId].name).replace("〓",""));
        fileList[fId].rename(afterNameArr[i]);
        log[i]=log[i]+" → " + fileList[fId].name
    }

    myDlg.close();
    alert(decodeURI(log.join("\n")))
}

function existInArr(arr, tgt) {
    existInArr = false;
    var arrLen = arr.length;
    for (var p = 0; p < arrLen; p++) {
        if (arr[p] === tgt) {
            return true;
        }
    }
}

function getIdInArr(arr, tgt) {
    getIdInArr = false;
    var arrLen = arr.length;
    for (var p = 0; p < arrLen; p++) {
        if (arr[p] === tgt) {
            return p;
        }
    }
}

function chkDuplicates(arr) {
    var exist = {};
    var result = [];
    for (var i = 0, l = arr.length; i < l; i++) {
        var tmp = arr[i];
        if (!exist[tmp]) {
            exist[tmp] = true;
        } else {
            result.push(tmp);
        }
    }
    return result;
}

メモ

わかったこと

File、Folderオブジェクトのnameは読み取り専用。リネームする場合はrenameメソッドを使用する。

積み残し

  • rename()の戻り値(リネームできたかどうか)もアラートに表示する。
  • 「仮に〓をつけて重複を避ける」以外のやり方を考える。
  • decodeURI()、encodeURI()のタイミングを再考。何度も使っているけれど、もう少し回数を絞れるのでは。