Help defining condition to find 'matching filenames

Hello Everyone,

this is my first time here and I hope I will not break any of the rules of the community.

What I would like to do is to make Hazel find file pairs with the same filename (although different extensions). If there is a file pair like this then move both files to a specific folder.



  • these files have the same filename but different extensions. In my case, it will always be a pair of a .jpg and a .mobi or .epub file.

Many thanks for your help!

ps. If not in Hazel I could also try KM or any other software to achieve this.

Finding things is easy enough - you could use Spotlight to do it. But what do you want to do with the resulting files?

E.g. if you want to put Waterpolo.jpg and Waterpolo.epub into. folder together, you could use Hazel’s Sort into subfolder action to put them both into a folder called Waterpolo.

Many thanks for your reply.

For me, the first part i.e. finding two files that have matching filenames is the hard part. To be precise: the thing is that I don’t know beforehand what their name will be. The only thing I know is that there will be pairs of files with matching names. I hope I am describing the issue correctly.

So the rule I am looking for would be phrased like this:

  1. Check if there are two files that have matching filenames.
  2. If so then move both files to to ‘File pairs’

Here’s a way to think about tackling it, and I’m sure it could be a little more efficient if you processed it based on the file being processed in Hazel, but I’m imagining the volumes are such that it won’t make any practical difference in the amount of time to process. So, this is presented on the basis that you run it each time a new file is added, and it will simply process the entire directory each time.

I took this approach because Hazel is based around processing a single file at a time, but you want to process sets of files in concert rather than individual files.

For the Hazel rule, process any file by running a shell script - you can make it stand alone or embedded as you see fit and matches how you manage your scripts.


Here’s my test folder:


In it I have four JPG files, where one has no matched pair (bar.jpg), one has a single matching EPUB (foo.jpg), one has a single matching MOBI (baz.jpg), and for good measure, one has both a matching EPUB and a matching MOBI (qua.jpg). I assume that you could get the latter if you added the EPUB and MOBI files first and then the JPG afterwards as it is the JPG that acts as the trigger. For info, the inverse of this scenario where the JPG is added first is why I didn’t make the Hazel rule match only on JPG files - i.e. the matching files may come in later, and before another JPG file arrives to trigger anything.

The logic is in the shell script. So that you can test things out first before using it, the script is purposefully dummied so that it will not do anything … I’ll explain.

  • Every file move command I have prefixed with echo, so that it will just output to the command line what it would do. When yoiu are ready to use it, simply replace all of the echo mv strings with just mv.
  • The script should be customised to meet your particular requirements through the settings:
    • dirSrc = the path to the folder you are processing in Hazel.
    • dirMatch = the path to the folder where you want to move matched files too
    • extMain = the file extension of the must have file (e.g. JPG)
    • extAlt1 = a file extension of an optional match file (e.g. EPUB)
    • extAlt2 = a file extension of an optional match file (e.g. MOBI)

Make sure you modify the settings in the script below and modify the dummied moves when you are ready to use it.


# Settings

# Change to the directory we want to process
cd $dirSrc

# Check all files in the directory
for file in *.$extMain
	echo checking "\"$file\""...
	# Move Alt1 file if it exists, along with the original
	if [[ -e ${file%%$extMain}$extAlt1 ]]; then
		echo mv "$dirSrc/${file%%$extMain}$extAlt1" "$dirMatch/${file%%$extMain}$extAlt1"
		echo mv "$dirSrc/$file" "$dirMatch/$file"
	# Move Alt2 file if it exists, along with the original if that exists
	if [[ -e ${file%%$extMain}$extAlt2 ]]; then
		echo mv "$dirSrc/${file%%$extMain}$extAlt2" "$dirMatch/${file%%$extMain}$extAlt2"
		# Only try and move the original if that is still there
		if [ -f $file ]; then
			echo mv "$dirSrc/$file" "$dirMatch/$file"

If I run this as is on my system, with the files as above, I get the following output:

checking "bar.jpg"...

checking "baz.jpg"...
mv /Users/stephen/Temp/check/ /Users/stephen/Temp/match/
mv /Users/stephen/Temp/check/baz.jpg /Users/stephen/Temp/match/baz.jpg

checking "foo.jpg"...
mv /Users/stephen/Temp/check/foo.epub /Users/stephen/Temp/match/foo.epub
mv /Users/stephen/Temp/check/foo.jpg /Users/stephen/Temp/match/foo.jpg

checking "quz.jpg"...
mv /Users/stephen/Temp/check/quz.epub /Users/stephen/Temp/match/quz.epub
mv /Users/stephen/Temp/check/quz.jpg /Users/stephen/Temp/match/quz.jpg
mv /Users/stephen/Temp/check/ /Users/stephen/Temp/match/
mv /Users/stephen/Temp/check/quz.jpg /Users/stephen/Temp/match/quz.jpg

Now, if I modify the script to do the moves rather than just echoing the commands and walk through the results.

Starting with the source and match folder listings of this:

Then running the script standalone, the output is this:

checking "bar.jpg"...

checking "baz.jpg"...

checking "foo.jpg"...

checking "quz.jpg"...

The resulting listings become:

All of the matching files have been moved.

Hopefully, that all makes sense, and meets your needs.

Dear Sylumer,

I am very impressed. I don’t know I can express my gratitude for the time you’ve spent to help find a solution to my problem. I will need a day or two to implement this as I am not an expert in automation but I am sure it will work! Many thanks again. All to best to you in the New Year!