Automator/AppleScript: move folders to a location based on their name

applescriptautomatorfinderscript

I'm very new to scripting and Automator but I am trying to figure out a way to have folders automatically moved to a desired location based on the beginning and ending of their names. for example:

If folder name starts with "A" and ends with "45" move to Documents/Archive/A/45

or

if folder name starts with "J" and ends with "29" move to Documents/Archive/J/29

Edit:

  1. Real world folder name would be: A761245 or J647929
  2. Yes the destination folders already exist
  3. No, the source folder and destination folder are in different locations.
  4. I'm running macOS Mojave 10.14.6⁩

Is there a way to do this with automator or scripting? Thank you!

Best Answer

I opened Terminal, which by default opens to ones home directory, and ran the following command:

mkdir -p  ./Documents/Archive/A/45 ./Documents/Archive/J/29 A761245 J647929


This created two new directories, A761245 and J647929, in the root of my home directory and the hierarchal directory structure within my Documents directory to receive them when moved.

I then use the following compound command to move any directory whose name started with an upper case alpha character followed by six numeric characters:

for d in *; do [[ -d $d ]] || continue; if [[ $d =~ ^([A-Z])([0-9]{4})([0-9]{2})$ ]]; then mv -n -v "$d" "./Documents/Archive/${BASH_REMATCH[1]}/${BASH_REMATCH[3]}/"; fi; done


The result of this compound command was:

A761245 -> ./Documents/Archive/A/45/A761245
J647929 -> ./Documents/Archive/J/29/J647929
$


This compound command could be used in a bash script, e.g.:

#!/bin/bash

for d in *; do
    [[ -d $d ]] || continue
    if [[ $d =~ ^([A-Z])([0-9]{4})([0-9]{2})$ ]]; then
        mv -n -v "$d" "./Documents/Archive/${BASH_REMATCH[1]}/${BASH_REMATCH[3]}/"
    fi
done


This basically works by testing the name of any directory passed to conform to an upper case alpha character followed by six numeric characters using capture groups and BASH_REMATCH to build the appropriate destination pathname for the mv command.

I know you said the destination directories already exist and the example bash code above takes that for granted without any additional error handling. With that said though, you could add a line of code that would create the necessary hierarchal directory structure first, as in the example below:

#!/bin/bash

for d in *; do
    [[ -d $d ]] || continue
    if [[ $d =~ ^([A-Z])([0-9]{4})([0-9]{2})$ ]]; then
        mkdir -p "./Documents/Archive/${BASH_REMATCH[1]}/${BASH_REMATCH[3]}"
        mv -n -v "$d" "./Documents/Archive/${BASH_REMATCH[1]}/${BASH_REMATCH[3]}/"
    fi
done


The one-liner compound command would be:

for d in *; do [[ -d $d ]] || continue; if [[ $d =~ ^([A-Z])([0-9]{4})([0-9]{2})$ ]]; then mkdir -p "./Documents/Archive/${BASH_REMATCH[1]}/${BASH_REMATCH[3]}"; mv -n -v "$d" "./Documents/Archive/${BASH_REMATCH[1]}/${BASH_REMATCH[3]}/"; fi; done


I'd use this version of the compound command and or bash script.


Note: Using the -p option with the mkdir command will create the hierarchal directory structure as needed without erring out if it already exists. This would be that way I'd go just to make sure you do not try moving a source directory to a nonexistent destination directory.