Macos – How to change the appearance of empty folders in finder using Automator

automatorbashfindermacosshell-script

I'm trying to use Apple Automator to label empty folders in a heirarchy. Basically, I start off a project with a heirarchy of empty folders and fill them as I work. I want a workflow to label all empty folders (gray) that contain no files and their descendants also contain no files.

In other words, when I create the empty project, all folders should be gray, as there are no "files" anywhere, just empty folders. However, once I place a file somewhere, it's parent and all of it's grandparents would no longer be labeled gray.

I thought I found what I needed at How to change the appearance of empty folders in finder? however, it is labeling empty folders. In my project, only the last descendants would ever be gray because all of the parent folders contain folders, therefore, not empty.

Here's the code I'm running in a /bin/bash shell script in Automator:

find "$@" -type d -empty

And then I'm passing it to a "Label finder items" to turn the results gray.

Here's the result I'm getting when run on a test folder:

  • Test Folder (not gray)
    • Folder One (gray)
    • Folder Two (not gray)
      • Folder A (gray)
    • Folder Three (not gray)
      • Test.txt
    • Folder Four (not gray)
      • Folder A (not gray)
        • Test.txt

And here's the result I'm looking for:

  • Test Folder (not gray)
    • Folder One (gray)
    • Folder Two (gray)
      • Folder A (gray)
    • Folder Three (not gray)
      • Test.txt
    • Folder Four (not gray)
      • Folder A (not gray)
        • Test.txt

Any help will be GREATLY appreciated!

Oh, also, I beleive I can run the workflow from Hazel. If you have a better way to have it automatically run occasionally, I'd love to know that as well.

Thanks.

Edit: Just realized that the .ds_store files (I assume) are causing folders to also not appear empty, if, for instance, I delete the last file in a folder.

Best Answer

I tried a few cases, and seems it works as you need:

Shell script, usr/bin/perl, pass input as arguments.

automator service

use File::Find;

find({ wanted => \&find_files, no_chdir => 1 }, @ARGV);

sub find_files
{
    if (-f $_)
    {
        ($file) = $_ =~ /.*\/(.*)$/;
        push (@all_files, $_) if ($file ne ".DS_Store");
    }
    else
    {
        push (@all_folders, $_);
    }
}

sub osascript($) { system 'osascript', map { ('-e', $_) } split(/\r/, $_[0]); } 

foreach(@all_files)
{
    @paths = split(/\//, $_);
    for $i (0..$#paths-1)
    {
        if ($i == 0)
        {
            $x = "$paths[$i]";
        }
        else
        {
            $x = "$last[$i-1]/$paths[$i]";
        }
        push(@last, $x);
        $temp{$x} ++;
    }
    @last = ();
 }

@not_gray_folders = keys %temp;
foreach(@all_folders)
{
    $folder = $_; $flag = 0;
    foreach(@not_gray_folders)
    {
        if ($folder eq $_)
        {
            $flag = 1;
        }
    }
    if (!$flag)
    {
        $label = 7;
    }
    else
    {
        $label = 0;
    }
    &osascript ("tell application \"Finder\" to set label index of alias POSIX file \"$folder\" to $label");
}
Related Question