Use Case
- Normally I like to use native, non-scripting, KM Actions when I can, as long as they are effective and reasonably efficient.
- The main challenge in this case was identifying the subfolder which ended in a specific suffix. The AppleScript for this is easy:
set subFolderList to folders of mainFolderAlias whose name ends with subFolderSuffix
- However, use of the Finder for this can be very slow.
-
Macro/script has been updated to use System Events -- much, much faster.
set subFolderList to (disk items of mainFolderAlias whose name ends with subFolderSuffix and visible is true)
- In this case, I could not find the equivalent KM Actions to perform the same function as the below AppleScript.
- If anyone knows of a non-scripting solution, please feel free to post below.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UPDATED: 2019-06-17 23:19 GMT-5
~~~ VER: 1.1 2019-06-17 ~~~
- Replaced script section that used Finder with System Events to greatly improve the performance.
- Will now process all subfolders with the specified suffix
- Now provides option to replace identical files in the Main folder
MACRO: Move All Files in Selected SubFolders to Parent Folder [Example]
~~~ VER: 1.1 2019-06-17 ~~~
DOWNLOAD:
(Note download file (macro) name is different from above title)
Move All Folders in Source Folder to Different Folder [Example].kmmacros (21 KB)
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.
ReleaseNotes
Author.@JMichaelTX
PURPOSE:
-
Move All Items in SubFolder with Suffix to Main Folder
- SubFolders identified by a given sufix
- May have more than one subfolder with this suffix
- Option to Replace Items with the same name in Main Folder (else error)
HOW TO USE
- First, make sure you have followed instructions in the Macro Setup below.
- Trigger this macro.
MACRO SETUP
-
Carefully review the Release Notes and the Macro Actions
- Make sure you understand what the Macro will do.
- You are responsible for running the Macro, not me. ??
.
- Assign a Trigger to this maro.
- Move this macro to a Macro Group that is only Active when you need this Macro.
- ENABLE this Macro.
.
-
REVIEW/CHANGE THE FOLLOWING MACRO ACTIONS:
(all shown in the magenta color)- Set Variable "Local__MainFolder"
- POSIX path to folder
- Set Variable "Local__SubFolderSuffix"
- All subfolders with this suffix will be processed
- Set Variable "Local__ReplaceFiles"
- Set to "Yes" to replace existing files in Main Folder
- Set Variable "Local__MainFolder"
REQUIRES:
- KM 8.2+
- macOS 10.11.6 (El Capitan)
TAGS: @Finder @Files @Folder @AppleScript
USER SETTINGS:
- Any Action in magenta color is designed to be changed by end-user
ACTION COLOR CODES
- To facilitate the reading, customizing, and maintenance of this macro,
key Actions are colored as follows: - GREEN -- Key Comments designed to highlight main sections of macro
- MAGENTA -- Actions designed to be customized by user
- YELLOW -- Primary Actions (usually the main purpose of the macro)
- ORANGE -- Actions that permanently destroy Variables or Clipboards,
OR IF/THEN and PAUSE Actions
USE AT YOUR OWN RISK
- While I have given this a modest amout of testing, and to the best of my knowledge will do no harm, I cannot guarantee it.
- If you have any doubts or questions:
- Ask first
- Turn on the KM Debugger from the KM Status Menu, and step through the macro, making sure you understand what it is doing with each Action.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
property ptyScriptName : "Move All Items from SubFolder to Main Folder"
property ptyScriptVer : "1.1" -- CHG Method Used to Select Items to use System Events
property ptyScriptDate : "2019-06-17"
property ptyScriptAuthor : "JMichaelTX" -- based on scripts by @CJK & @ccstone
(*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PURPOSE:
• Move All Items in SubFolder with Suffix to Main Folder
• SubFolders identified by a given sufix
• May have one or more subfolders with this suffix
• Option to Replace Items with the same name in Main Folder
RETURNS:
• "OK" on the first line
• TBD on subsequent lines
• OR, "[ERROR]" & error details
KM VARIABLES REQUIRED: (must be set before calling this script)
• Local__MainFolder
• Local__SubFolderSuffix
• Local__ReplaceFiles
REQUIRED:
1. macOS El Capitan 10.11.6+
(may work on Yosemite 10.10.5, but no guarantees)
2. Mac Applications
• Keyboard Maestro 8.2+
1. 2019-06-17, ccstone, Keyboard Maestro Discourse
Move All Folders in Source Folder to Different Folder [Example]
https://forum.keyboardmaestro.com/t/move-all-folders-in-source-folder-to-different-folder-example/14016/7?u=jmichaeltx
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)
use AppleScript version "2.5" -- El Capitan (10.11) or later
use scripting additions
## Some Scripts may work with Yosemite, but no guarantees ##
# This script has been tested ONLY in macOS 10.14.5 (Mojave)
property LF : linefeed
property CR : return
global gCurrentApp
set gCurrentApp to path to frontmost application as text -- use for dialogs
set scriptResults to "TBD"
try
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Requires Keyboard Maestro 8.0.3+ ###
set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
set mainFolder to getvariable "Local__MainFolder" instance kmInst
set subFolderSuffix to getvariable "Local__SubFolderSuffix" instance kmInst
set replaceFiles to getvariable "Local__ReplaceFiles" instance kmInst
end tell
set replaceFilesBool to false
if (replaceFiles = "Yes") then set replaceFilesBool to true
(*
### FOR TESTING ###
set mainFolder to POSIX path of (path to home folder) & "Documents/TEST"
set subFolderSuffix to "mkv"
set replaceFilesBool to true
### END TESTING ###
*)
if ((mainFolder = "") or (subFolderSuffix = "")) then
error "The following KM Variables must bet set before calling this script:" & ¬
LF & " • " & "Local__MainFolder" & ¬
LF & " • " & "Local__SubFolderSuffix"
end if
set mainFolderAlias to POSIX file mainFolder as alias
(*
--- Using Finder Works, but can be very slow ---
tell application "Finder" to set subFolderList to folders of mainFolderAlias whose name ends with subFolderSuffix
--- Using System Events is Almost as Fast as using ASObjC ---
But you still have to use Finder to move to trash (security limitations)
--- My upmost thanks to Chris Stone (@ccstone) for helping me work out the details
of using System Events to get file list to move
*)
tell application "System Events"
set subFolderList to (disk items of mainFolderAlias whose name ends with subFolderSuffix and visible is true)
repeat with oFolder in subFolderList
set itemList to (disk items of oFolder whose visible is true)
--- IF USER WANTS TO REPLACE EXISTING FILES ---
if (replaceFilesBool) then
repeat with oItem in itemList
try -- IF Creating Alias works, then the file exists in the Destination Folder --
set oFile to ((mainFolderAlias as text) & (name of oItem)) as alias
tell application "Finder" to move oFile to trash -- can't use System Events for this
end try
end repeat
end if -- replaceFilesBool
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
move itemList to mainFolderAlias
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end repeat
end tell -- "System Events"
set scriptResults to "OK"
--~~~~~~~~~~~~~ END TRY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on error errMsg number errNum
if errNum = -128 then ## User Canceled
set errMsg to "[USER_CANCELED]"
end if
set scriptResults to "[ERROR]" & return & errMsg & return & return ¬
& "SCRIPT: " & ptyScriptName & " Ver: " & ptyScriptVer & return ¬
& "Error Number: " & errNum
end try
--~~~~~~~~~~~~~~~~END ON ERROR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- RETURN THE RESULTS TO THE KM EXECUTE SCRIPT ACTION ---
return scriptResults