Richhawk106
Richhawk106

Reputation: 31

Google Script - Compare file name to folder name and move file in to folder if name matches

I'm trying to compare my google drive folder names to some file names and then if there is a match - move the file to the respective folder.

i.e -

folders:
example1,
example2,
example3,

files:
example1.jpg (move to folder - example1),
example2.jpg (move to folder - example2),
example3.jpg (move to folder - example3)

So far I have two arrays with the folder and file names which I am looping over and comparing the two.

I'm struggling with the next bit - moving the file to the folder.

This is what I've got so far...

function folderAndFiles(){

  var fileArray = [];
  var folderArray = [];

  var dApp = DriveApp;
  var folderIter = dApp.getFoldersByName("files");
  var folder = folderIter.next();
  var fileIter = dApp.getFiles();
  var filesIter = folder.getFiles();



  while(filesIter.hasNext()) {
    var file = filesIter.next();
    var fileName = file.getName();
    fileArray.push(fileName)

  }

  fileArray.sort();
  var newFiles = fileArray.map(function(d) { return d.replace('.jpg', ''); });
  Logger.log(newFiles);



  var folderIterTwo = dApp.getFoldersByName("names");
  var folderTwo = folderIterTwo.next();
  var nameFolders = folderTwo.getFolders();



  while(nameFolders.hasNext()) {
    var folders =  nameFolders.next();
    var names = folders.getName();
    folderArray.push(names)

  }

  folderArray.sort();
  Logger.log(folderArray);



  for (var i = 0; i < folderArray.length; i++) {
    for (var j = 0; j < newFiles.length; j++) {
        if (folderArray[i] == newFiles[j]) {
         folderArray[i].addFile(fileArray[i]);
          Logger.log("Moved");
        }
    }
  }


}

Any help would be greatly appreciated!

Thanks!

Upvotes: 2

Views: 1131

Answers (2)

carlesgg97
carlesgg97

Reputation: 4430

Try the code below:

function folderAndFiles(){
  var files = [];
  var folderMap = {};

  var foldersParent = DriveApp.getFoldersByName("names").next();
  var filesParent = DriveApp.getFoldersByName("files").next();

  var filesIterator = filesParent.getFiles();
  var foldersIterator = foldersParent.getFolders();

  while(filesIterator.hasNext()) {
    var currentFile = filesIterator.next();
    files.push(currentFile);
  }

  while(foldersIterator.hasNext()) {
    var currentFolder =  foldersIterator.next();
    folderMap[currentFolder.getName()] = currentFolder;
  }

  for (var i=0; i<files.length; i++) {
    var file = files[i];
    var fileName = file.getName().replace('.jpg', '');
    var destinationFolder = folderMap[fileName];

    if (destinationFolder) {
      destinationFolder.addFile(files[i]);
      filesParent.removeFile(file);
      Logger.log("Moved");
    }
  }
}

The flow of the program is the following:

  1. Create a list with all the files to move.

  2. Create a dictionary that maps the names of the folders to the actual folder object.

  3. For each file:

    1. Compute its name (remove the extension).
    2. Check whether there is a folder with that name.
    3. In case there is, move the file in question to that folder.

Note that the file is actually moved - it is added to the new folder, but also removed from the original one. If you want to just copy it, remove the line filesParent.removeFile(file); of the code.

Upvotes: 3

tehhowch
tehhowch

Reputation: 9862

This should be a partial solution, which will help you implement the rest:

/**
 * @param {string} [parentFolderName] Name of the folder within which to search (defaults to Drive root)
 * @returns {Array <{ name: string, file: File }>} an array of objects with the properties 'name' (containing a string) and 'file' (containing the File object reference)
 */
function getNamedDriveFiles_(parentFolderName) {
  var parent = DriveApp.getRootFolder();
  if (parentFolderName) {
    var matches = DriveApp.getFoldersByName(parentFolderName);
    if (!matches.hasNext()) {
      throw new Error('No folder with name "' + parentFolderName + '"');
    }
    parent = matches.next();
  }
  const results = [];
  var iterator = parent.getFiles();
  while (iterator.hasNext()) {
    var file = iterator.next();
    // Store an object with the name of the file, and the File object itself
    results.push({ name: file.getName(), file: file });
  }
  return results;
}

function doStuff() {
  const files = getNamedDriveFiles_('my cool folder');
  files.sort(function (a, b) {
    return a.name < b.name;
  });
  // print filesizes
  files.forEach(function (obj) {
    Logger.log('Filename: "' + obj.name + '"; size: ' + obj.file.getSize());
  });
}

You should be able to implement a similar function for your folder objects, and then can easily reference the File and Folder for a given filename and foldername.

Upvotes: 0

Related Questions