Amazonで商品を見るセール会場へ

Googleドライブ│フォルダ内のファイル名を一括リネーム!文字列を置換して自動変更する方法

フォルダー直下のファイル名を一括で置換するには、変更前の名前とIDを保存し、置換結果を先に確認します。

この記事のGASは子フォルダーへ入らず、ファイル名だけを変更します。

本文やファイルの保存先は変更しません。

実際の業務フォルダーを使う前に、専用の練習フォルダーで確認してください。

目次

ファイル名を変更する前の確認手順

実行の順番です。内容は、この記事の説明とコードにもとづく目安です。このスクリプトは、Googleドライブのファイル名を書き換えます。必ず、専用の練習フォルダーで、先に確認してください。記事では、掲載したGASのDrive権限取得と書き換えは、未実行です。

  1. 専用の練習フォルダーを用意する。実際の業務のフォルダーでは、最初に試さない。
  2. 新規のApps Scriptプロジェクトに、コードを貼り付け、RENAME_FOLDER_IDを練習用フォルダーのURLにあるIDに置き換える。RENAME_FROMとRENAME_TOに、置換前・置換後の文字列を設定する。
  3. まず、previewRenameを実行する。ファイル名は変更されず、実行ログに、id・before・afterが出る。これを保存する。
  4. 対象件数とすべての名前を確認し、意図どおりの場合だけ、applyRenameを実行する。
  5. Googleの権限確認が出た場合は、対象プロジェクトとDriveの要求権限を、自分で確認する。
  6. 途中で止まったときは、doneIdsだけでなく保存した計画内の全IDを照合する。現在の名前を確認し、実際に変更されたファイルだけを元に戻す。

途中で失敗しても、一括では取り消せません。必ず、previewRenameの結果(id・変更前の名前)を保存してから、applyRenameを実行してください。

スポンサーリンク

入力例と置換後の名前

変更前最初の1箇所を置換すべてを置換
sample_sample.txtサンプル_sample.txtサンプル_サンプル.txt
sample.txtサンプル.txtサンプル.txt
notes.txtnotes.txt:変更しないnotes.txt:変更しない

RENAME_ALLがfalseなら最初の1箇所だけ、trueならすべての同じ文字列を置換します。

正規表現ではなく文字列を使う例です。

拡張子も名前の一部なので、置換前の文字列が拡張子に含まれる場合は結果を確認してください。

sample_sample.txtの最初のsampleだけがサンプルへ変わり子フォルダーは残っている
名前変更の実画面。専用ファイルをDrive APIで変更し、同じIDのまま元の名前へ戻せることも確認しました。掲載GASの実行画面ではありません。

プレビューと変更を分けた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は、保存した計画と現在のフォルダーID・ファイルID・変更前後の名前を比較します。ファイルの追加・削除・名前の変更や、置換設定の変更によって結果が変わった場合は、事前確認で停止します。設定を変えても計画の内容が同じ場合は停止しないため、設定変更後はpreviewRenameをやり直して結果を確認してください。

直前確認の後に別の人が名前を変える競合までロックできる処理ではありません。

共同編集を止めた専用対象で使います。

変更不要のファイルはsetNameを呼びません。

Drive APIによる専用ファイルの名前変更では、sample_sample.txtからサンプル_sample.txtへ変わり、同じID・保存先・30バイトのサイズが維持されました。

読み取った本文も練習テキストと一致しました。

さらに元の名前へ戻せることを確認しました。

一方、掲載GASのDrive権限取得と書き換えは未実行です。

コードは構文確認と明示的なNode模擬検証を行ったもので、実画面をGASの実行証拠として扱っていません。

途中で止まったときと戻し方

途中失敗は一括取消になりません。

doneIdsは、setNameから正常に戻った後に記録したIDです。エラー時の完全な変更一覧とは限りません。通信や実行の中断で、名前が変わっていてもログに残らない場合に備え、previewRenameで保存した計画内の全IDについて、現在の名前とbefore・afterを照合します。

同じ名前のファイルがあっても、元のURLのIDで対象を開きます。現在名がbeforeなら変更不要です。afterになっているファイルは元の名前へ戻す対象ですが、復旧前に他の人の変更がないか確認してください。

別の人がさらに名前を変えていた場合は上書きせず調整します。

プレビューをやり直すと保存済みの計画を置き換えます。

復旧が必要な場合は、先に前のログとスクリプトプロパティを保存します。

失敗後に同じ処理を繰り返さず、現在の名前を確認してください。

練習用ファイル・コード・ローカル検証をまとめたZIPには同名衝突・対象増加・途中失敗などの模擬検証が含まれます。

公式仕様と関連する操作

Folder.getFilesの公式仕様とFile.setNameの公式仕様を確認できます。

コピーを先に作る場合はGoogleドライブ│フォルダー直下のファイルをまとめてコピーする方法、共同作業者の範囲はGoogleドライブ│共有設定と権限の違い|閲覧者・コメント可・編集者・リンク共有を確認してください。

関連する既存記事と案内

関連する既存記事と商品案内を以下に掲載しています。

練習は本文の対象範囲を確認して進め、未検証の実行を確認済みとして扱わないでください。

スポンサーリンク

よくある質問:Googleドライブのファイル名を一括リネームするときのチェックリスト

このスクリプトは、何をしますか?

フォルダー直下のファイル名を、一括で置換します。変更前の名前とIDを保存し、置換結果を先に確認する、プレビューと変更を分けたコードです。

子フォルダーの中のファイルも、変更されますか?

されません。この記事のGASは、子フォルダーへ入らず、ファイル名だけを変更します。本文やファイルの保存先は、変更しません。

最初の1箇所だけでなく、すべて置換するには?

RENAME_ALLの設定で切り替えます。RENAME_ALLがfalseなら最初の1箇所だけ、trueならすべての同じ文字列を置換します。正規表現ではなく、文字列を置換する例です。

拡張子も、置換されますか?

拡張子も名前の一部なので、置換前の文字列が拡張子に含まれる場合は、結果を確認してください。

何ファイルまで、処理できますか?

処理対象は直下50ファイル以内で、置換後の同名衝突、空の検索文字列、空の結果名を事前に止めると説明しています。

プレビュー後に、ファイルを追加したり、設定を変えたりすると、どうなりますか?

保存した計画と現在のフォルダーID・ファイルID・変更前後の名前が異なれば、applyRenameは事前確認で停止します。置換設定を変えても計画の内容が同じ場合は停止しません。設定変更後はpreviewRenameをやり直し、結果を確認してください。ただし、直前確認の後に別の人が名前を変える競合までは、ロックできません。共同編集を止めた専用対象で使います。

名前を間違えて変更したときは、元に戻せますか?

途中失敗は、一括取消になりません。doneIdsだけでは変更をすべて把握できない場合があります。保存した計画内の全IDを開き、現在名をbefore・afterと照合して、実際に変更された対象だけを元に戻します。別の人がさらに名前を変えていた場合は、上書きせず調整します。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

スプレッドシート・GASのおすすめ書籍

作業環境の作り方

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次