Select Files in the Front Finder Window Based on Name Criteria

Hi and thanks for your help!

Is there a way to select all files at the same time based on a criteria?

Here I would like to select all the ones containing " Jane" in 1 go.It won't always be in the same folder, so it should work in my current location.

Screen Shot 2022-09-20 at 10.31.46 PM

Screen Shot 2022-09-20 at 10.33.43 PM

Yes. But why do you want to do that? Normally you select files to do something -- you may find it easier to go straight to "do a thing to all the files whose name contains 'Jane'".

Is it always the same thing to do? The same criteria?

By current location, do you mean the frontmost Finder window? The folder containing an already-selected file? A location previously referenced in the macro? Should this include matching files in sub-folders?

So many questions! It's usually worth taking a moment to explain your workflow so people can see where the thing you're asking about sits -- more suggestions on how to help us help you are in Tip: How Do I Get The Best Answer in the Shortest Time?

1 Like

You’re right, let me try to be more specific.

I would like to select all the files containing “ Jane” (space Jane) to put them in a new folder that I will rename “To Delete” right we’re I’m currently am in the Finder (like it would select them and do Cmd Ctrl N). The files I’m looking to select will always have this format “NameOfTheExcelDoc Jane”. There will be a file that is already selected in my Finder window before this step in my macro but it won’t be a correct one, meaning it won’t be one containing “ Jane”.

All of this happening in the front finder window so that I’m not stuck to a specific location.

Thank you!!

Hey Nicolas,

The simplest way to do this is to type F in the front Finder window to access the search field.

Then type:

name:"jane"

This will only work nicely if you don't have items with "Jane" in the title buried in subfolders though.

To get more sophisticated you'll have to use AppleScript.

-Chris

1 Like

It's all too easy when making a macro to to fall into the "I'll get KM to emulate what I do" trap. That often means we're playing to our weaknesses rather than KM's strengths and, importantly, we're trying to automate the GUI when we really shouldn't:

set the selected files to none
for each file in the front Finder window
    if name contains " Jane" then add it to the selected files
end
move the selected files to a new folder
rename the new folder to "To Delete"

GUI automations are much more fragile than "programmatic" macros -- they usually rely on the GUI being in a known state and can be broken by an accidental mouse click, your email client popping to the front, even an unusual sort order in a window. While you can try and catch many of these it's a lot more, often unnecessary, work.

But programmatically:

get path to folder shown in frontmost Finder window
for each item in that folder
    if name contains " Jane" then move to folder "To Delete" in that folder
end for

...which looks very similar to the previous outline. But the important difference is that we only reference the GUI once, in the very first line, which means there's far less chance of something throwing a spanner in the works. You may not even need to do that -- it still feels like you've only presented a small section of a bigger workflow and you could probably determine the path to the frontmost window even earlier in the process and use it throughout.

Enough of the explanation of why this (hopefully!) does what you want but in a different way to how you've stated it -- the above should also help you to adjust it where required. To the macro!

Moving Janes.kmmacros (4.7 KB)

Image

5 Likes

Wow....this is amaaazing! You're always dropping some great knowledge and perfect macros! I manage to include it in my bigger macro, thank you very much!!

Hey Guys,

I should have mentioned that Keyboard Maestro is quite capable of doing this – thanks Nige.

It's inefficient to move files piecemeal, although this method is be perfectly adequate for a variety of jobs.

Here's how to move them all at once using the Finder via AppleScript:

--------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2022/09/23 12:21
# dMod: 2022/09/23 12:21 
# Appl: Finder
# Task: Move Files Whose Name Contains a Keyword.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Finder, @Move, @Files, @Keyword
--------------------------------------------------------

property keyWord : "Jane"

--------------------------------------------------------

tell application "Finder"
   
   set insertionLocation to insertion location as alias
   set deleteFolder to (make new folder at insertionLocation with properties {name:"Delete"}) as alias
   set fileList to files of insertionLocation as alias list
   
   repeat with theFile in fileList
      if name of theFile does not contain keyWord then
         set contents of theFile to 0
      end if
   end repeat
   
   set filesToMove to aliases of fileList
   
   move filesToMove to deleteFolder
   
end tell

--------------------------------------------------------

This is a very vanilla method.

The task can be done faster and with more sophistication using AppleScriptObjC, and files can be identified using a regular expression instead of just a keyword.

-Chris

1 Like

Very interesting! Will give it a short! THANK YOU!

Getting shorter:

tell application "Finder"
	set insertionLocation to insertion location as alias
	set deleteFolder to (make new folder at insertionLocation with properties {name:"To Delete"}) as alias
	move (every file of insertionLocation whose name contains " Jane") to deleteFolder	
end tell

Downside is that it isn't as precise as the KM version in that it doesn't move only those files whose name, excluding extension, ends with " Jane" and that it creates a "To Delete" folder even if there's nothing to move. The second is easily solved with either try/error block similar to the try/catch in the macro or an "if empty folder then delete" at the end, but the first means going back to your "loopy" method and adding in some further text processing.

1 Like

This looks great and I will def test it! Thank you so much!

The bigger downside is that, whilst in theory, this would be the right approach, Finder's limitations make many situations perform worse with a whose filter and subject to timeouts. Often the best approach with Finder is an iterative one that's thoughtfully constructed.

Actually, the best approach with Finder is to steer clear except for the absolute bare essentials. Invoke Finder to retrieve the insertion location, but pass this to System Events for the grunt work.

try blocks are a plague upon the house of AppleScript, although that's probably quite fitting since AppleScript itself is mostly built from a big band aid covering over the stuff that was never worth the time to fix. But this is one situation we can avoid the error-masking whilst avoiding errors and do so without additional effort:

tell application id "com.apple.finder" to tell (get the insertion location) ¬
	    to if (the folder "To Delete" exists) or (exists (make new folder ¬
	    at it with properties {name:"To Delete"})) then move (files whose ¬
	    name contains " Jane") to the folder "To Delete"

The use of boolean logic here wasn't essential, as this could have been done over multiple lines, but it's kinda cool to know that AppleScript doesn't go through the effort of evaluating the parts of a boolean statement when doing so wouldn't change the outcome (i.e. lazy evaluation).

3 Likes

Thank you so much for contributing! This works great!

1 Like

That is... beautiful.

I'd never thought of using lazy evaluation in AS, though being familiar with it in other contexts (eg perl's (doSomething || die) -- one for the toolbox.

My only worry would be whether I could understand what it's doing in a year's time! As a very occasional scripter (I've probably written more AS in my last few months on the forum than in the previous 5 years!) I do tend to "easy mode" at the expense of efficiency. I need to up my game, and your code and explanations are a real help in that.

Same caveat as with the other AppleScript posts in the thread -- as written these will move files that contain " Jane" anywhere in their name. I know you used "containing" in your OP, but all your example files have it at the end of the name but before the extension.

If your files all follow the same naming convention as your examples that probably won't be a problem, but something like From Janet - HHKMS107.xlsx would get moved even though it shouldn't be.

2 Likes

I didn't notice that, but you're right. A marginal refinement could be conferred by using " Jane.xlsx" or, if the extension is likely to vary, then " Jane." (retaining the period).

I also like these sorts of language constructs available in other languages. I suppose we get what we're given wifh AppleScript, but there's elegance to be found in its oafishness, and constructing mammoth one-liners can often be more about the hilarity than the efficiency. It's possible to crowbar AppleScript syntax together while adhering perfectly well to its grammar, and create some of the most unnatural compound expressions that few people would rush to describe as "natural language sounding", such as this one to find Safari tabs that contain a particular string:

tell application id "com.apple.Safari" to if ¬
	running then tell its every window to if ¬
	it exists then tell (it whose (index of ¬
	tab 1 whose URL contains www) is in the ¬
	index of every tab) to return every tab ¬
	whose URL contains www

(which is just the first example I had to hand, but there are finer, uglier examples that are also somehow quite lovely.)

2 Likes