英文:
AppScript Question - Deleting Duplicate File Names
问题
以下是翻译好的内容:
晚上好,
我正在尝试找出一种自动从Google Drive文件夹中删除重复文件名的方法。我想保留创建日期最旧的文件,将其他文件视为重复文件并删除它们。
我感觉离实现这个目标已经很接近,使用下面的AppScript代码(来自此网站:https://hackernoon.com/how-to-find-and-delete-duplicate-files-in-google-drive)。唯一的问题是,该代码似乎保留了最新的文件而不是最旧的文件。您知道我可以做什么来修改此代码,以保留最旧的文件而不是最新的文件吗?如果您有其他代码来实现我的目标,请也分享一下。
谢谢!
const FOLDER_ID = "在此处插入文件夹的ID";
// 添加要检查重复的文件夹的ID
/*
* 此函数在指定文件夹中查找重复文件名并删除它们。
* @param {String} fileName
*/
function removeDuplicateFile() {
let folder = DriveApp.getFolderById(FOLDER_ID);
let files = folder.getFiles();
let fileList = [];
// 如果没有找到文件,则返回null
if (!files.hasNext()) {
return;
}
// 否则
while (files.hasNext()) {
let file = files.next(),
name = file.getName(),
size = file.getSize();
// 以这种方式检查总是保留第一个文件不被删除
if (isDuplicateFile(fileList, name, size)) {
file.setTrashed(true);
} else {
fileList.push([name, size]);
}
}
}
/*
* 此函数是removeDuplicateFile函数的辅助函数。
* 它检查给定的列表中是否已经存在具有相同名称和大小的文件,然后返回true或false。
* @param {List} lst
* @param {String} name
* @param {Number} size
* @returns {Boolean}
*/
function isDuplicateFile(lst, name, size) {
for (let i = 0; i < lst.length; i++) {
if (lst[i][0] === name && lst[i][1] === size) return true;
}
return false;
}
/*
* 如果存在任何触发器,则删除所有触发器
*/
var deleteTrigger = () => {
let triggersCollection = ScriptApp.getProjectTriggers();
if (triggersCollection.length <= 0) {
console.log(`事件没有触发器ID`);
} else {
triggersCollection.forEach((trigger) => ScriptApp.deleteTrigger(trigger));
}
return;
};
/*
* 为文件创建一个触发器函数,如果存在先删除之前的触发器。
*/
function removeDuplicateFileTrigger() {
// 首先删除现有的触发器
deleteTrigger();
// 现在删除重复文件
removeDuplicateFile();
}
英文:
Good evening,
I am trying to figure out a way to automatically delete files with duplicate filenames from a Google Drive folder. I'd like to keep the file with the oldest creation date, treat the others as duplicates, and delete the duplicates.
I feel close to achieving this using the below AppScript code (from this site: https://hackernoon.com/how-to-find-and-delete-duplicate-files-in-google-drive). The only issue is the code is seemingly keeping the newest file instead of the oldest one. Do you know what I can do to shift this code to keep the oldest file instead of the newest one? If you have other code in mind to achieve my goal, please also share that.
Thank you!
const FOLDER_ID = "INSERTIDHERE";
// Add id of the folder to check for duplicate
/*
* Function looks for duplicate file names in designated folder and removes them.
* @param {String} fileName
*/
function removeDuplicateFile() {
let folder = DriveApp.getFolderById(FOLDER_ID);
let files = folder.getFiles();
let fileList = [];
// if no file is found return null
if (!files.hasNext()) {
return;
}
// else
while (files.hasNext()) {
let file = files.next(),
name = file.getName(),
size = file.getSize();
// checking this way always leaves first file not deleted
if (isDuplicateFile(fileList, name, size)) {
file.setTrashed(true);
} else {
fileList.push([name, size]);
}
}
}
/*
* Function is helper function of removeDuplicateFile function.
* It checks if theres already a file in the given lst with same name and size and returns true or false
* @param {List} lst
* @param {String} name
* @param {Number} size
* @returns {Boolean}
*/
function isDuplicateFile(lst, name, size) {
for (let i = 0; i < lst.length; i++) {
if (lst[i][0] === name && lst[i][1] === size) return true;
}
return false;
}
/*
* Delete all the triggers if there are any
*/
var deleteTrigger = () => {
let triggersCollection = ScriptApp.getProjectTriggers();
if (triggersCollection.length <= 0) {
console.log(`Event doesnot have trigger id`);
} else {
triggersCollection.forEach((trigger) => ScriptApp.deleteTrigger(trigger));
}
return;
};
/*
* Create a trigger function for file which also deletes previous triggers if there are.
*/
function removeDuplicateFileTrigger() {
// First Delete existing triggers
deleteTrigger();
// now remove duplicate files
removeDuplicateFile();
}
答案1
得分: 1
我相信您的目标如下。
- 您想要删除重复的文件。在这种情况下,您希望保留最旧的文件作为创建日期。
在您的脚本中,没有包含用于检查创建日期的脚本。那么,在这种情况下,如何修改以下内容呢?在这个修改中,函数 removeDuplicateFile()
被修改如下。
修改后的脚本:
function removeDuplicateFile() {
let folder = DriveApp.getFolderById(FOLDER_ID);
let files = folder.getFiles();
if (!files.hasNext()) {
return;
}
// 通过解析文件名和文件大小来检索文件。
let list = {};
while (files.hasNext()) {
let file = files.next(),
name = file.getName(),
size = file.getSize(),
date = file.getDateCreated().getTime();
let key = name + size;
list[key] = list[key] ? [...list[key], { file, size, date }] : [{ file, size, date }];
}
// 保留最旧的文件。
let removeFiles = Object.values(list).reduce((ar, v) => {
if (v.length > 1) {
let [, ...f] = v.sort((a, b) => a.date > b.date ? 1 : -1);
ar = [...ar, ...f.map(({ file }) => file)];
}
return ar;
}, []);
// 删除除了最旧文件之外的文件。
removeFiles.forEach(f => f.setTrashed(true));
}
- 运行此脚本时,通过检查文件名和文件大小来检索文件列表。然后,删除重复的文件,同时保留最旧创建的文件。
- 在此修改中,您的
isDuplicateFile
没有被使用。
参考链接:
英文:
I believe your goal is as follows.
- You want to remove the duplicate files. In this case, you want to leave the oldest files as the created date.
In your script, the script for checking the created date is not included. So, in this case, how about the following modification? In this modification, the function removeDuplicateFile()
is modified as follows.
Modified script:
function removeDuplicateFile() {
let folder = DriveApp.getFolderById(FOLDER_ID);
let files = folder.getFiles();
if (!files.hasNext()) {
return;
}
// Retrieve files by parsing the filename and the file size.
let list = {};
while (files.hasNext()) {
let file = files.next(),
name = file.getName(),
size = file.getSize(),
date = file.getDateCreated().getTime();
let key = name + size;
list[key] = list[key] ? [...list[key], { file, size, date }] : [{ file, size, date }];
}
// Keep the oldest files.
let removeFiles = Object.values(list).reduce((ar, v) => {
if (v.length > 1) {
let [, ...f] = v.sort((a, b) => a.date > b.date ? 1 : -1);
ar = [...ar, ...f.map(({ file }) => file)];
}
return ar;
}, []);
// Remove files except for the oldest files.
removeFiles.forEach(f => f.setTrashed(true));
}
- When this script is run, the file list is retrieved by checking the filename and the file size. And, the duplicated files are removed while the oldest created files are left.
- In this modification, your
isDuplicateFile
is not used.
References:
答案2
得分: 1
保留 Google Drive 中最旧文件并删除重复文件的备选解决方案
请注意启用 Drive API。
function keepOldestFilesOfEachNameInAFolder() {
const folder = DriveApp.getFolderById("插入文件夹ID");
const files = folder.getFiles();
let fO = { pA: [] };
let keep = [];
while (files.hasNext()) {
let file = files.next();
let n = file.getName();
// 在 fO 中组织文件信息
if (!fO.hasOwnProperty(n)) {
fO[n] = [];
fO[n].push(file);
fO.pA.push(n);
} else {
fO[n].push(file);
}
}
// 对具有相同名称的每个组进行排序
fO.pA.forEach(n => {
fO[n].sort((a, b) => {
let va = new Date(a.getDateCreated()).valueOf();
let vb = new Date(b.getDateCreated()).valueOf();
return va - vb; // 我已修改此行以保留最旧的文件而不是最新创建的文件
});
// 保留最旧的文件并删除其余文件
fO[n].forEach((f, i) => {
if (i > 0) {
Drive.Files.remove(f.getId());
}
});
});
}
英文:
Alternative Solution to retain the oldest file and delete duplicate files in Google Drive
Please note to enable Drive API.
function keepOldestFilesOfEachNameInAFolder() {
const folder = DriveApp.getFolderById("INSERT FOLDER ID");
const files = folder.getFiles();
let fO = { pA: [] };
let keep = [];
while (files.hasNext()) {
let file = files.next();
let n = file.getName();
//Organize file info in fO
if (!fO.hasOwnProperty(n)) {
fO[n] = [];
fO[n].push(file);
fO.pA.push(n);
} else {
fO[n].push(file);
}
}
//Sort each group with same name
fO.pA.forEach(n => {
fO[n].sort((a, b) => {
let va = new Date(a.getDateCreated()).valueOf();
let vb = new Date(b.getDateCreated()).valueOf();
return va - vb; // I have modified this line to retain the oldest one instead of the newest files created
});
//Keep the oldest one and delete the rest
fO[n].forEach((f, i) => {
if (i > 0) {
Drive.Files.remove(f.getId());
}
});
});
}
答案3
得分: 0
function removeDuplicateFile() {
const folder = DriveApp.getFolderById("fid");
const files = folder.getFiles();
let fObj = { pA: [] };
// 将具有相同名称的所有文件收集到一个数组对象中
while (files.hasNext()) {
let f = files.next();
let n = f.getName();
let dv = f.getDateCreated().valueOf();
let id = f.getId();
if (!fObj.hasOwnProperty(n)) {
fObj[n] = [{ name: n, value: dv, id: id }];
fObj.pA.push(n);
} else {
fObj[n].push({ name: n, value: dv, id: id });
}
}
fObj.pA.forEach(p => {
fObj[p].sort((a, b) => b.value - a.value); // 按创建日期降序排序
fObj[p].forEach((ob, i) => {
if (i > 0) {
Drive.Files.remove(ob.id); // 永久删除文件
}
});
});
}
您可能需要启用 Drive API。
英文:
function removeDuplicateFile() {
const folder = DriveApp.getFolderById("fid");
const files = folder.getFiles();
let fObj = { pA: [] };
//collect all files with same names into an object of arrays
while (files.hasNext()) {
let f = files.next();
let n = f.getName();
let dv = f.getDateCreated().valueOf();
let id = f.getId();
if (!fObj.hasOwnProperty(n)) {
fObj[n] = [{ name: n, value: dv, id: id }];
fObj.pA.push(n);
} else {
fObj[n].push({ name: n, value: dv, id: id });
}
}
fObj.pA.forEach(p => {
fObj.sort((a, b) => b.value - a.value);//sort descending by date created
fObj
.forEach((ob,i) => {
if(i > 0) {
Drive.Files.remove(ob.id);//deletes files permanently
}
});
});
}
You may need to enable Drive API
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论