Automate moving and renaming files

applescriptautomatorfinderfolders

I have files nested within multiple sub-folders. I want to move these files, one folder up the folder structure and rename the files as per its new parent folder. I will need this to be automated with a script.

Example logic

  1. Find Root folder
  2. Get contents of Subfolder of Subfolder files.
  3. Move files to its Parent folder (aka 'Attachments' folder)
  4. Rename files to with its current Parent folder name.
  5. Delete empty Subfolder
  6. Loop above action of Root folder folders until complete.

Renaming details

Attachments folder could one to many file of .png or .jpg. For example, Attachments folder could have Apple.png and Dog-house.jpg. If these files are moved and renamed, I'm expecting the file name to be something like this MCP##-##### - abc.png and MCP##-##### - abc.jpg.

If there is more then one file with the same file type, then the naming to be something like this MCP##-##### - abc.png and MCP##-##### - abc (1).png

Example folder structure

enter image description here

Desired Result

![enter image description here

I'm assuming this may require to Automate with a script but I have no idea how to do it. Can anyone help me?

Best Answer

The following is an example Automator workflow that achieves the stated goal of your question per its defined hierarchal folder structure.

NOTE: While the example bash code used in the Run Shell Script action completed successfully nonetheless, the onus is upon the user to ensure that proper backups exist before using it. I'd even suggest making a small sample copy of the target hierarchal folder structure to test with before running the workflow on the original target.

For the purpose of testing this workflow, the following hierarchal folder structure with its files was created:

$ tree ./Applications
./Applications
├── MCP19-00633 - Sport and Play at Br
│   └── Attachments
│       ├── barfoo.png
│       ├── filename.jpg
│       ├── filename.png
│       └── foobar.jpg
├── MCP19-00753 - Active Nabiac
│   └── Attachments
│       ├── barfoo.png
│       ├── filename.jpg
│       ├── filename.png
│       └── foobar.jpg
└── MCP19-00824 - A Family Friendly Ve
    └── Attachments
        ├── barfoo.jpg
        ├── barfoo.png
        ├── filename.jpg
        ├── filename.png
        ├── foobar.jpg
        ├── namefile.jpg
        └── namefile.png

6 directories, 15 files
$ 

The results of the Automator workflow run on the target above:

$ tree ./Applications
./Applications
├── MCP19-00633 - Sport and Play at Br
│   ├── MCP19-00633 - Sport and Play at Br (1).jpg
│   ├── MCP19-00633 - Sport and Play at Br (1).png
│   ├── MCP19-00633 - Sport and Play at Br.jpg
│   └── MCP19-00633 - Sport and Play at Br.png
├── MCP19-00753 - Active Nabiac
│   ├── MCP19-00753 - Active Nabiac (1).jpg
│   ├── MCP19-00753 - Active Nabiac (1).png
│   ├── MCP19-00753 - Active Nabiac.jpg
│   └── MCP19-00753 - Active Nabiac.png
└── MCP19-00824 - A Family Friendly Ve
    ├── MCP19-00824 - A Family Friendly Ve (1).jpg
    ├── MCP19-00824 - A Family Friendly Ve (1).png
    ├── MCP19-00824 - A Family Friendly Ve (2).jpg
    ├── MCP19-00824 - A Family Friendly Ve (2).png
    ├── MCP19-00824 - A Family Friendly Ve (3).jpg
    ├── MCP19-00824 - A Family Friendly Ve.jpg
    └── MCP19-00824 - A Family Friendly Ve.png

3 directories, 15 files
$ 

The image below of the example Automator workflow contains the actions used and their particular settings used from their defaults. Be sure to match the settings shown in the image. In particular, the Get Folder Contents action has the [√] Repeat for each subfolder found checked, and the Run Shell Script action has Pass input: set to as arguments.

Automator workflow Image


Example bash code:

for f in "$@"; do

    [[ -f $f ]] || continue

        ext="${f##*.}"
        move_to_dir="$(dirname "$(dirname "$f")")"
        filename="$(basename "$move_to_dir")"

        cd "$move_to_dir" || exit

        if [[ ! -e ${filename}.${ext} ]]; then
            mv "$f" "${filename}.${ext}"
        else
            n=1
            for i in "${filename}" *".${ext}"; do
                if [[ "${filename} (${n}).${ext}" == "$i" ]]; then
                    n=$(( n + 1 ))
                fi
            done
            mv "$f" "${filename} (${n}).${ext}"
        fi
done

for d in "$@"; do
    [[ -d $d ]] || continue
    [[ $(basename "$d") == Attachments ]] || continue
    rmdir "$d"
done

Note: The example bash code is just that and only contains minimal error handling, and was checked using ShellCheck. However, it may not contain all appropriate needed/wanted error handling. The onus is upon the user to add any error handling as may be appropriate, needed or wanted.

Related Question