Simplified nested IF THEN?

Today I was trying to figure out how to check folders for a single file:

Now I would like to create a more complex macro where I use multiple files.
I can create the macro with multiple IF THEN actions, but I was wondering if there's a simplified version that uses variables, maybe?

So I have 7 files and I want to check if 14 folders have those files or not.

Starting with "File1", KM would check if "Folder1" contains that file. It will do this for each folder until it finds one that doesn't and moves that file to that folder, for example Folder7.
The list of folders came from a variable and I'm using the For Each action, so it checks them in order top to bottom.

Then it checks "File2", same thing.

And every time it moves a file, it stops checking the remaining folders, because that would show an error, since the File would no longer be available. So if it moves File1 to Folder7, it will stop checking Folder8 through Folder14 and it starts checking File2.

If File2 is moved to Folder10, Folder11 through Folder 14 wouldn't be checked for File2. It would jump to File3, etc...

Hope it makes sense.

This is the only way I can think of:
Move file to folder.kmmacros (48 KB)

I'm sure there is a simpler way?
So basically, every time a certain file is added to the folder, it checks if it's a specific file (that's the IF THEN actions).

If so, it checks each variable line and moves a certain file to a certain folder and cancels the macro. If not, it goes to the next IF THEN action, and so on...

I was writing it down on paper and if I want to use another variable with the names of the files, it seems like it needs nested IF THEN actions. I was trying to use a variable with all the files the macro needs to check, but can't seem to find a way that's not "messy".

@Zabobon, here's what I need:

Check if there's a File 1 inside Folder 1
- If "NO", move File 1 to Folder 1, stop checking all the other folders for File 1 and start checking File 2 inside Folder 1, etc
- If "YES", check if there's a File 1 inside Folder 2
--- If "NO", move File 1 to Folder 2, stop checking all the other folders for File 1 and and start checking File 3 inside Folder 1, etc
--- If "YES", check if there's a File 1 is inside Folder 3

and so on...
Does it make sense?

I was thinking of using a variable with all the files and use a For Each, but it gets a bit messy and I'm not sure if that's the way to go.

I mean, the one I have now works as expected. I was just wondering if there's a simpler way? If I was using 100 files instead of 7, it would be a huge macro and hard to maintain if something changes.

Are the files you want to move, all in the same folder to begin with?

Yes. Basically what I'm doing is I'm exporting all images from Photoshop into a folder called "_All Images".
This Photoshop file is a template where only one image changes (1 per song). So when I export the images, even though they are different in terms of graphics, the names are the same such as Facebook Feed.png, Instagram Story.png, etc.

Now when I export them, I want KM to automatically send them to a folder where those files aren't present yet. So when I work on the images for song 2 and export them, there will be no images inside _All Images and then KM checks which folder doesn't have this images. In this case, since I already exported images for song 1, it would move those exported images to folder Song 2, etc. I have 14 folders to check, because that's my workflow, working on 14 songs at the same time and exporting everything for all 14 songs

Okay, I think the way I would approach this is to have a For Each which iterates through the files you have placed in the folder "_All Images". So, it looks at each of those files one at a time (i.e. the first file in the folder might be called "Facebook-Feed.png" or whatever you've called it). And it gets the filename to a Variable.

Then within that, have a nested For Each which checks each of the folders you have in "Songs" (i.e. folders called, "Song 1" "Song 2" "Song 3" or whatever those folders are called) and if the first folder hasn't got "Facebook-Feed.png" in it that file will be moved from "_All Images" into that folder and the loop is broken, which causes the Macro to check the next file and so on.

If the folder already has a file in it called ""Facebook-Feed.png", then the loop moves to the next Folder "Song 2" and does the check again.

There could be any number of images in the "_All Images" folder (called whatever you want) and any number of Songs folders (called whatever you want) in the "Songs" Folder.

For testing I had a source folder of images like this:
(Could be any number of images, called whatever)

And a destination "Songs" folder like this:
(Could be any number of Song Folders, called whatever)

This example Macro is set up to "move" the files. But for testing it is probably better to set that Action to "copy" and try it out on dummy files and folders until you are sure it works for you.

Click to Show Image of Macro

Move files to Subfolders if not already there.kmmacros (4.9 KB)


If it's the file name that's being compared, rather than the file contents, and if it's guaranteed that none of the files or subfiles in Songs have the same name, (which is not clear to me) then I have a totally different approach.

(1) Create a variable that contains a list of the following two things separated by a comma for each of the files in both the Images and Songs folders: (a) the path names, and (b) the files names... it's critical that these two things be separated by a comma in a single line. All of the filenames from both the Images file and the Songs file go into the same file, as I said. This is crucial. I'm assuming that no filename or folder name contains a comma.
(2) Sort the file and extract all the items with "unique" filenames, and save this in a separate variable. (This represents the filenames which do NOT have a match.)
(3) Use the diff command to get the differences between the full list of files and this subset list, which results in the names of all files (and their corresponding folders) that DO have a match.
(4) Using this list of matches, it should be simple to take the action that you want.

My solutions often take approaches that people don't like. (And sometimes my solutions are wrong.) This approach of mine can, for the most part, be written in a single KM action which executes a shell script which contains about three shell commands.

1 Like

Thanks for the alternative approach.
I haven't tested this approach, but one thing I notice (at least from what I read) is that if I'm dealing with dozens or even hundreds of files, that would be a mess to update each path and file names. The same if I decide to move those files to a different location.

@Zabobon approach works for me and it seems to be the approach that makes it easier and faster to update the macro.
I appreciate your alternative, though

My method only has you listing the names of the folders, not the files. I thought you said there were 14 folders.

Thank you so much for sharing this.
You were able to put into a macro what I had in mind and on paper. Just couldn't figure out how to achieve it.

I made a small change to your macro, because I have other macros and also Hazel being dependent of certain paths and it would be a pain to update everything, so I'm using a variable for the paths instead


Thanks again. It's always great to learn something new!

1 Like

Yes in this case it's only 14 folders, but my goal is to always create a scenario where I can quickly make changes and rely on variables (or a single path, as @Zabobon used), because if I want to reuse this macro for a different scenario, then I would have to make a lot of changes using your approach.

You did mention file names. If I wanted to use different files, I would have to update the file names as well. With @Zabobon approach, I don't even have to think about that, as long as my structure is built having the macro in mind. All I need is to set the Source path and the Destination path. In my particular case, I had to use a variable with the paths, just because I have other stuff dependent of the original paths already, otherwise, @Zabobon approach would be used as is with just the paths.

Aha! The reason were aren't able to resolve this is because you don't realize that my method automatically generates filenames using the paths that you manually enter. You can use Z's method, even though my method is almost entirely automatic (all you have to do is enter the 14 folder names manually.) Since you're happy, I'm happy.

1 Like