フォルダー直下のファイル名を一括で置換するには、変更前の名前とIDを保存し、置換結果を先に確認します。
この記事のGASは子フォルダーへ入らず、ファイル名だけを変更します。
本文やファイルの保存先は変更しません。
実際の業務フォルダーを使う前に、専用の練習フォルダーで確認してください。
入力例と置換後の名前
| 変更前 | 最初の1箇所を置換 | すべてを置換 |
|---|---|---|
| sample_sample.txt | サンプル_sample.txt | サンプル_サンプル.txt |
| sample.txt | サンプル.txt | サンプル.txt |
| notes.txt | notes.txt:変更しない | notes.txt:変更しない |
RENAME_ALLがfalseなら最初の1箇所だけ、trueならすべての同じ文字列を置換します。
正規表現ではなく文字列を使う例です。
拡張子も名前の一部なので、置換前の文字列が拡張子に含まれる場合は結果を確認してください。

プレビューと変更を分けたGASコード
新規のApps Scriptプロジェクトに貼り付け、RENAME_FOLDER_IDを練習用フォルダーのURLにあるIDへ置き換えます。
RENAME_FROMとRENAME_TOは置換前・置換後の文字列です。
処理対象は直下50ファイル以内で、置換後の同名衝突、空の検索文字列、空の結果名を事前に止めます。
const RENAME_FOLDER_ID = '練習用フォルダーのID';
const RENAME_FROM = 'sample';
const RENAME_TO = 'サンプル';
const RENAME_ALL = false; // false: 最初の1箇所、true: すべて
const RENAME_PLAN_KEY = 'cgmRenamePlanV1';
function collectRenamePlan_() {
if (!RENAME_FROM) throw new Error('置換前の文字列を空にしないでください');
const folder = DriveApp.getFolderById(RENAME_FOLDER_ID);
const iterator = folder.getFiles(); // 直下のファイルだけ
const files = [];
while (iterator.hasNext()) {
if (files.length >= 50) throw new Error('練習対象は50ファイル以内です');
const file = iterator.next();
const before = file.getName();
const after = RENAME_ALL ? before.split(RENAME_FROM).join(RENAME_TO)
: before.replace(RENAME_FROM, () => RENAME_TO);
if (!after.trim()) throw new Error('空の名前になるファイルがあります');
files.push({ id: file.getId(), before, after });
}
const names = files.map(item => item.after);
if (new Set(names).size !== names.length) {
throw new Error('置換後の名前が重複します。変更前に整理してください');
}
return { folderId: RENAME_FOLDER_ID, files };
}
function previewRename() {
const plan = collectRenamePlan_();
const json = JSON.stringify(plan);
if (Utilities.newBlob(json).getBytes().length > 8000) {
throw new Error('保存する計画が大きすぎます。対象を減らしてください');
}
PropertiesService.getScriptProperties().setProperty(RENAME_PLAN_KEY, json);
console.log(JSON.stringify(plan, null, 2)); // 変更前の名前・IDを保存する
return plan;
}
function applyRename() {
const saved = PropertiesService.getScriptProperties().getProperty(RENAME_PLAN_KEY);
if (!saved) throw new Error('先にpreviewRenameを実行してください');
const plan = JSON.parse(saved);
const fresh = collectRenamePlan_();
const ordered = value => JSON.stringify(value.files.slice().sort((a,b) => a.id.localeCompare(b.id)));
if (plan.folderId !== fresh.folderId || ordered(plan) !== ordered(fresh)) {
throw new Error('プレビュー後に対象・名前・設定が変わりました。変更はしていません');
}
const done = [];
try {
for (const item of plan.files) {
if (item.before === item.after) continue;
DriveApp.getFileById(item.id).setName(item.after);
done.push(item.id);
}
} catch (error) {
console.log(JSON.stringify({ doneIds: done, error: String(error) }));
throw error; // 自動で再実行しない。保存済み計画で変更済みIDを確認する
}
console.log(JSON.stringify({ changed: done.length, doneIds: done }));
}
実行と結果の確認
まずpreviewRenameを選んで実行し、実行ログに出るid・before・afterを保存します。
ファイル名は変更されませんが、計画はこのプロジェクトのスクリプトプロパティに保存されます。
次に対象件数とすべての名前を確認し、意図どおりの場合だけapplyRenameを実行します。
Googleの権限確認が出た場合は、対象プロジェクトとDriveの要求権限を自分で確認してください。
プレビュー後にファイルの追加・削除・名前や置換設定の変更があれば、applyRenameは事前確認で停止します。
直前確認の後に別の人が名前を変える競合までロックできる処理ではありません。
共同編集を止めた専用対象で使います。
変更不要のファイルはsetNameを呼びません。
Drive APIによる専用ファイルの名前変更では、sample_sample.txtからサンプル_sample.txtへ変わり、同じID・保存先・30バイトのサイズが維持されました。
読み取った本文も練習テキストと一致しました。
さらに元の名前へ戻せることを確認しました。
一方、掲載GASのDrive権限取得と書き換えは未実行です。
コードは構文確認と明示的なNode模擬検証を行ったもので、実画面をGASの実行証拠として扱っていません。
途中で止まったときと戻し方
途中失敗は一括取消になりません。
実行ログのdoneIdsと、previewRenameで保存したID・変更前の名前を照合し、変更済みのファイルだけを確認します。
同じ名前のファイルがあっても、元のURLのIDで対象を開き、名前を元に戻してください。
別の人がさらに名前を変えていた場合は上書きせず調整します。
プレビューをやり直すと保存済みの計画を置き換えます。
復旧が必要な場合は、先に前のログとスクリプトプロパティを保存します。
失敗後に同じ処理を繰り返さず、現在の名前を確認してください。
練習用ファイル・コード・ローカル検証をまとめたZIPには同名衝突・対象増加・途中失敗などの模擬検証が含まれます。
公式仕様と関連する操作
Folder.getFilesの公式仕様とFile.setNameの公式仕様を確認できます。
コピーを先に作る場合はGoogleドライブ│フォルダー直下のファイルをまとめてコピーする方法、共同作業者の範囲はGoogleドライブ│共有設定と権限の違い|閲覧者・コメント可・編集者・リンク共有を確認してください。
関連する既存記事と案内
関連する既存記事と商品案内を以下に掲載しています。
練習は本文の対象範囲を確認して進め、未検証の実行を確認済みとして扱わないでください。




