Scribble at 2026-03-27 07:20:13 Last modified: 2026-03-27 09:18:51
function deleteEverythingAdvanced() {
// --- 設定項目 ---
// 削除対象の拡張子リストを大幅に拡充
const extensions = [
'.js', '.css', '.html', '.jpg', '.gif', '.png',
'.pdf', '.md', '.json', '.psd', '.ts', '.mov', '.mp4',
'.txt', '.php', '.svg', '.map', '.jsm', '.woff', '.ttf', '.swf',
'.avi', '.dat', '.yml', '.pub', '.priv'
];
const batchSize = 300;
const pageSize = 1000;
// ---------------
let count = 0;
let pageToken = null;
const startTime = new Date().getTime();
const scriptId = ScriptApp.getScriptId();
try {
console.log("スキャンを開始します...");
do {
const options = {
q: "'root' in parents and trashed = false",
fields: "nextPageToken, files(id, name, mimeType)",
maxResults: pageSize,
pageToken: pageToken
};
const response = Drive.Files.list(options);
const files = response.files;
pageToken = response.nextPageToken;
if (files && files.length > 0) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (file.id === scriptId) continue;
const fileName = file.name;
const isFolder = (file.mimeType === 'application/vnd.google-apps.folder');
let shouldDelete = false;
// 1. フォルダの判定
if (isFolder) {
const isNumericFolder = /^\d+$/.test(fileName); // 桁数不問の数字のみ
const isTmpFolder = (fileName.toLowerCase() === 'tmp');
const isProfileFolder = (fileName.toLowerCase() === 'profile');
if (isNumericFolder || isTmpFolder || isProfileFolder) {
shouldDelete = true;
}
}
// 2. ファイルの判定
else {
const lowerName = fileName.toLowerCase();
const hasTargetExtension = extensions.some(ext => lowerName.endsWith(ext));
const hasNoExtension = !fileName.includes('.');
const isDotFile = fileName.startsWith('.');
if (hasTargetExtension || hasNoExtension || isDotFile) {
shouldDelete = true;
}
}
if (shouldDelete) {
Drive.Files.update({trashed: true}, file.id);
count++;
if (count % 50 === 0) console.log(`${count}個目のアイテムを処理中...`);
}
if (count >= batchSize) {
console.log(`目標の ${batchSize} 個を処理しました。次回の実行に引き継ぎます。`);
return;
}
}
}
// 5分経過でタイムアウト回避
if (new Date().getTime() - startTime > 300000) {
console.log("5分経過。一旦停止します。");
break;
}
if (pageToken) {
console.log(`次のページをスキャン中... (現在の削除数: ${count})`);
}
} while (pageToken);
console.log(`今回の実行全体で ${count} 個処理しました。`);
} catch (e) {
console.error("エラー発生: " + e.message);
}
}
GAS で5分おきのトリガーで走らせているスクリプトを示す。「マイドライブ」の直下にある対象ファイルやフォルダだけを「ゴミ箱」へ移動させるものだ。1,000個ずつアイテムをスキャンして、削除するアイテムにマッチしなければ次の1,000個・・・とページをめくってゆき、300個のファイルを削除するか、あるいは5分が経過したら処理を中断させる。なお、このスクリプトを実行するには、当然ながら GAS の管理画面で Google Drive API との連携が必要になる。
これを3月23日の14:00から開始して約90時間ほど回したところ、「マイドライブ」のサイズが 272 GB から 193 GB まで減っている。ただ、僕が作成して仕事に使っているフォルダは既に別の共有ドライブへ退避してあるから、残りの 193 GB も大半が不要なファイルやフォルダの筈であり、これらをスキャンして削除していくには、まだマッチしていない条件のファイルやフォルダがあろうと思う。たとえば ".zip" とかだ。ただ、こういう拡張子のファイルはアーカイブの目的で最初から「マイドライブ」の直下に僕自身が置いた可能性があるから迂闊に削除対象にできないので、エクスプローラなどファイル・マネージャで軽快に「マイドライブ」の直下をフリーズせずに表示できるようになった段階で確認しながら削除すればいいだろう。
ただ、ファイル・マネージャがフリーズせずにファイルやフォルダの一覧を表示できるのは、いったい何個くらいまで減らせばいいのやら分からない。かつて使っていた Firefox 用のアドオンである Scrapbook のデータ・フォルダも、大量のフォルダを抱えるため、ファイル・マネージャで中身を表示させようとすると酷い時間がかかったものだ。それでも、僕の記憶では数千個であればなんとかフリーズせずに表示していたと思う。ただ、そこまで減らそうと思えば、他に削除対象を増やしておかないといけないのだろう。
[追記:2026-03-27] 連れ合いと暫く話しているときに感じたのだが、このくらいの小さなコードでも、Gemini がすべて書いたわけでもなく、僕が手を入れたりしている個所もあるし、GitHub にプライベートのアカウントでも作って、そこへ公開しておこうかと思う。仕事では既にアカウントを持っているけれど、そこは案件のリポジトリなどで殆どの内容が非公開だから、そこへプライベートなコードを置くのは憚られる。