No internet connection
  1. Home
  2. How to

How to sort files into different folders in Finder

By Andrew Sherman @Andrew_Sherman
    2022-06-29 10:54:42.094Z

    I'm trying to separate and sort files in Finder

    • In finder, a file is manually selected, or a folder is selected
    • the script is triggered
    • If no files are selected (and a folder is selected), then the script should act on the all files within the selected folder
    • Otherwise if a file or multiple files are selected, the script should act on all the files within the parent folder
    • File extensions are noted by SoundFlow
    • New folders created with the names of the file extensions
    • Folder names should be capitalised
    • Files with matching extension moved into new folder

    For example if the folder contains
    P100713.jpg
    P100713.RW2
    P100714.jpg
    P100714.RW2
    P100715.jpg
    P100715.RW2
    The .jpg files would be moved into a new folder called JPG
    The .RW2 files would be moved into a new folder called RW2

    Some folders might contain more than 2 filetypes.

    This is what I have so far but I'm getting stuck. I know it's not complete but I don't know which direction to go. Do you have any pointers?

    
    /* 
    Separate files by type and move into new folders
    */
    
    sf.ui.finder.appActivate();
    
    var fullPath = sf.ui.finder.firstSelectedPath;
    
    var directory = fullPath.split('/').slice(0, -1).join('/');
    var filenameFirst = fullPath.split('/').slice(-1)[0];
    var extension = filenameFirst.split('.').slice(-1)[0];
    var extensionFolder = directory + '/' + extension;
    
    // log(extensionFolder)
    
    sf.engine.runInBackground(() => {
    
        function moveToFolder() {
    
            sf.ui.finder.selectedPaths.forEach(filePath => {
                // Get each file name
                var fileName = filePath.split('/').slice(-1)[0];
                var destinationFile = extensionFolder + '/' + fileName;
    
                // Move files
                sf.file.move({
                    sourcePath: filePath,
                    destinationPath: `${destinationFile}`
                });
    
            });
        }
    
        moveToFolder();
    
    });
    
    Solved in post #4, click to view
    • 8 replies
    1. samuel henriques @samuel_henriques
        2022-07-01 13:03:34.214Z

        Hello Andrew,
        I didn't test your script, but it looks like you were going the correct way.
        Here's my take on this.

        const selectedPaths = sf.ui.finder.selectedPaths
        if (selectedPaths.length === 0) { alert("Please Select Files or Folders."); throw 0; };
        
        const firstSelectedPath = selectedPaths[0]
        const isFolder = firstSelectedPath.charAt(firstSelectedPath.length - 1) === "/"
        let filePaths
        
        if (isFolder) {
            filePaths = sf.file.directoryGetFiles({
                path: selectedPaths[0],
            }).paths
        } else {
            filePaths = selectedPaths
        }
        
        
        filePaths.forEach(filePath => {
        
            const locationPath = filePath.split("/").slice(0, -1).join("/")
            const fileName = filePath.split("/")[filePath.split("/").length - 1]
            const extention = filePath.split(".")[filePath.split(".").length - 1]
            const destinationPath = locationPath + "/" + extention + "/" + fileName
            const destinationFolder = locationPath + "/" + extention + "/"
        
            sf.file.directoryCreate({
                path: destinationFolder
            });
        
            sf.file.move({
                sourcePath: filePath,
                destinationPath: destinationPath
            });
        
        });
        
        1. AAndrew Sherman @Andrew_Sherman
            2022-07-01 14:39:21.423Z

            Thank you Samuel, this is great. I'm going to make a few tweaks to it and I'll upload the result here in case anyone needs it.

            1. AAndrew Sherman @Andrew_Sherman
                2022-07-20 09:39:05.210Z2022-07-20 13:28:43.434Z

                Hi Samuel, I hope you're well.

                I have made some tweaks to this script (if only one file is selected, then it first selects all and runs the script.

                however it seems to run quite slowly when doing it like that; the processing time for the folder method or multiple files selected method seems to be quicker. Do you know why this might be?

                
                /* 
                Separate files by type and move into new folders
                https://forum.soundflow.org/-7947/how-to-sort-files-into-different-folders-in-finder#post-2
                */
                
                sf.ui.finder.appActivate();
                
                const selectedPaths = sf.ui.finder.selectedPaths;
                
                if (selectedPaths.length === 0) { alert("Please select a folder."); throw 0; };
                
                const firstSelectedPath = selectedPaths[0];
                const isFolder = firstSelectedPath.charAt(firstSelectedPath.length - 1) === "/";
                let filePaths;
                var fileQuantity = selectedPaths.length;
                
                if (fileQuantity > 1) {
                    if (isFolder) {
                        filePaths = sf.file.directoryGetFiles({
                            path: selectedPaths[0],
                        }).paths
                    } else {
                        filePaths = selectedPaths
                    }
                } else if (fileQuantity == 1) {
                
                    if (isFolder) {
                        filePaths = sf.file.directoryGetFiles({
                            path: selectedPaths[0],
                        }).paths
                    } else {
                        sf.ui.finder.menuClick({
                            menuPath: ["Edit", "Select All"]
                        })
                        filePaths = sf.ui.finder.selectedPaths
                    }
                }
                
                filePaths.forEach(filePath => {
                
                    const locationPath = filePath.split("/").slice(0, -1).join("/");
                    const fileName = filePath.split("/")[filePath.split("/").length - 1];
                    const extention = filePath.split(".")[filePath.split(".").length - 1];
                    const destinationPath = locationPath + "/" + extention + "/" + fileName;
                    const destinationFolder = locationPath + "/" + extention + "/";
                
                    if (extention !== "DS_Store") {
                
                        sf.file.directoryCreate({
                            path: destinationFolder
                        });
                
                        sf.file.move({
                            sourcePath: filePath,
                            destinationPath: destinationPath
                        });
                
                    }
                
                });
                
                ReplySolution
                1. samuel henriques @samuel_henriques
                    2022-07-20 12:53:53.440Z2022-07-20 13:05:59.560Z

                    Hey Andrew,
                    I'm away from my computer, so I can't test. But I think I would approach this differently.
                    If it's not DS_Store....

                    if (extention !== "DS_Store"){
                    /// Do stuff
                    }
                    
                    1. AAndrew Sherman @Andrew_Sherman
                        2022-07-20 13:27:59.286Z

                        Great, that's nice and simple. I've updated the code above it include this now.

                  • J
                    In reply toAndrew_Sherman:
                    Johan Nordin @Johan_Nordin
                      2023-10-30 18:53:23.843Z

                      Hello! I was searching for almpost exactly what this script is doing. Really good job with this one!

                      I tried to make some adjustments, but my coding knowledge is still not good enough. So I was wondering if @Andrew_Sherman or @samuel_henriques would like to give my adjustments a try. This is what I would like to add to the existing script:

                      1. If there's only one file type, nothing happens. :) My plan is to use this script at the and of another script, and I only want the script to launch if there's more than one file extension type. For example, if there's only wave files in the folder, everything stays as it is.

                      2. If there's a file extensions missing for some of the files, it could make an alert, for example "One or more files doesn't have a file extension." This one is not necessary, but I thought if the script is already checking the number of file types, why not make something of all possible outcomes.

                      3. If there's .mov or .mp4 files, the scrips puts theese files into a folder called "previews" instead of the file extension name.

                      Best regards, Johan Nordin

                      1. AAndrew Sherman @Andrew_Sherman
                          2023-10-31 08:49:07.973Z

                          Hi Johan, this should be easy enough to do with if/else statements. What I normally do is use Chat GPT with an example of the script as well as a detailed description of the changes that I'm looking for, you should be able to get some progress with that

                          1. JJohan Nordin @Johan_Nordin
                              2023-10-31 11:17:26.970Z

                              That's a really smart way!! Thanks for the idea. :)