Move files with replacement

I am trying to build a simple macro to move file to a destination folder. Sometimes the macro fails, due to a file with the same name already existing in the destination folder. The “Move (or Rename) File” action does not have any option to overwrite destination.
Other than an “If Then Else” action checking if the destination is already there, and deleting it if it is the case, is there a different (easier/smarter) way to do it?

Hey Andrea,

KM will not overwrite a file by design. I think Peter should provide an overwrite-option, but that’s up to him - and there are easy alternatives.

The shell and AppleScript can both do the job with ease.

From an Execute Shell Action:

mv ~/test_directory/test_folder_src/Test_File_01.txt ~/test_directory/test_folder_dest/

From an Execute AppleScript Action:

set srcFile to alias "Ryoko:Users:chris:test_directory:test_folder_src:Test_File_01.txt"
set destFldr to alias "Ryoko:Users:chris:test_directory:test_folder_dest:"

tell application "Finder"
  move srcFile to destFldr with replacing
end tell

Please note that posix-paths and hfs-paths are different animals and not interchangeable.

Best Regards,
Chris

1 Like

@ccstone, thanks for your answer.
I hadn’t thought of using a script, and it is indeed a good idea. The only point I’m struggling with now is how to pass the filename (and path) to the script. The move action is contained in a for each action, that iterates through the finder selection. I saw another discussion about a similar issue, Processing selected files in a python script, but I’m not sure I understand it that well. Besides, there the “execute shell action” calls a python script already on disc, whereas here it would be just a single command.
The solution in the original post works, I just feel it is a little too kludgy, and was looking for something more elegant. Your alternative fits the bill perfectly.

[quote=“agalli, post:3, topic:593”]
The move action is contained in a for each action, that iterates through the finder selection.[/quote]

Hey Andrea,

Why didn’t you say so! Easily done. :smile:

set destFldr to alias "Ryoko:Users:chris:test_directory:test_folder_dest:"

tell application "Finder"
  set finderSelection to selection as alias list
  if finderSelection ≠ {} then
    move finderSelection to destFldr with replacing
  end if
end tell

If you’re on Mountain Lion or Lion there’s a bug with the Finder-Selection that requires a simple workaround. It’s fixed in Mavericks (and I assume in Yosemite - but I won’t upgrade to Y-bugly until Apple fixes a few things and cannot therefore say for certain).

Here’s the workaround if needed:

set destFldr to alias "Ryoko:Users:chris:test_directory:test_folder_dest:"
tell application "Keyboard Maestro Engine" to activate
tell application "Finder"
  activate
  set finderSelection to selection as alias list
  if finderSelection ≠ {} then
    move finderSelection to destFldr with replacing
  end if
end tell

Note: you really don’t want to use this method for many hundreds of files, because the Finder will bog down - but a few hundred or less shouldn’t be a problem.

Best Regards,
Chris


Tags: @Finder, @Selection, @Finder-Selection, @Move, @File

Ok, then. just one step more :wink:
I would like to have multiple macros for different destination folder, and it seems “wasteful” to have the same script in different macros… so the move macro would be a sort of helper function, that gets the destination folder from the actual macro being run. For example, I would have a “Move to Pictures” macro and a “Move to Documents” macro, both taking the current Finder selection, but with different destination folders… Something similar to http://www.stairways.com/blog/2008-07-27-passing-parameters-to-applescript, but with the difference that the script is not on disk. The “Execute an AppleScript” action does not accept inputs, however.

Just to make it clear, I am perfectly happy with what you provided so far, now I’m just trying to improve my chops with KM…

Hey Andrea,

I wouldn't use that sort of parameter passing for this job. I'd just pass the destination path with a KM variable.

Note the use of ~/ throughout. It's an alias for your home-folder. Use that notation whenever possible, because it will survive changes in hard drive names, user-names, etcetera (unlike a hard-coded path).

I would also use a script file and not a text script, because it will execute more quickly.

Create a folder somewhere convenient like:

~/Library/Application Support/Keyboard Maestro/KM_AppleScript_Support/

Save your script with the Applescript Editor as script, and give it a descriptive name like:

Finder-Selection { Move Items to destFldr }.scpt

(I've provided the script and the KM-Macro below.)

Then all you have to do is duplicate the macro, rename it, drag & drop your new destination folder into the 'mvDest' variable field. Edit it appropriately if it can be turned into a tilde-path.

tell application "Keyboard Maestro Engine"
  set destFldr to value of variable "mvDest"
end tell

set destFldr to alias POSIX file destFldr

tell application "Finder"
  set finderSelection to selection as alias list
  if finderSelection ≠ {} then
    move finderSelection to destFldr with replacing
  end if
end tell

As you can see this sort of thing is extremely simple once you start learning how to put the pieces together.

Best Regards,
Chris


AppleScript with KM-Path-Parameter.kmmacros (2.3 KB)
Finder-Selection { Move Items to destFldr }.scpt.zip (4.5 KB)

@ccstone, thanks very much for your help.
I managed to adapt your script to my original "vision", and now am using an helper macro that contains only the applescript for moving the files:

The applescript get passed the destination folder and the files to be moved from the calling macro, like this:

I'm still using the "For Each Item" action. Your version where the AppleScript gets directly the full Finder selection is undoubtedly faster, but I'll check on my next step.

One advantage of using an AppleScript with the "tell Finder" block is that the whole macro can be reverted by pressing ⌘-z, unlike using the "Move (or Rename)" action directly.

Hey Andrea,

The reason I used the AppleScript was because it would initiate a move in the Finder for all the files at once, which is much more efficient than fiddling with them one at a time.

(Unless you’re dealing with a massive number of files.)

Best Regards,
Chris

Yes, that’s what I figured. In fact, I specifically wanted to try both versions to see how they performed, and in the end settled for the faster one. The clincher was the repeated sound of successful copy… :wink:

As I said, thanks very much for all your help

In case anybody else is interested, the final two macros are:

and adapt the second macro for a different destination folder.

1 Like

Hey Andrea,

You can trim that a trifle.

tell application "Keyboard Maestro Engine"
  set destFolder to the value of variable "destinationFolder"
end tell

set destFolder to alias POSIX file destFolder

tell application "Finder"
  set finderselection to selection as alias list
  if finderselection at {} then
    move finderselection to destFolder with replacing
  end if
end tell

Also - watch out for variable names that are confusing.

set fName to alias POSIX file fName

fName would generally refer to a name and not a file.

When you’re writing and maintaining code the less possibility of confusion the better.

Best Regards,
Chris