Skip to main content
m1b
Community Expert
Community Expert
August 23, 2023
Answered

[Extendscript] Best way to move a file via script.

  • August 23, 2023
  • 3 replies
  • 1602 views

Hi Scripters, does anyone know of the best way to move files via script? For example, here is one method that I got to work, but it has the bad side effect of destroying the file's created/modified dates because it duplicates the file into the desired location, then removes the original. I'm looking for something that works in Illustrator and is cross-platform. Any help would be much appreciated.

- Mark

(function () {

    // WARNING: do not run with an
    // important document open!

    // Example: takes the active document
    // and moves it into a "test" folder
    // created in its current folder
    var doc = app.activeDocument,
        docFile = doc.fullName,
        folder = Folder(docFile.parent.absoluteURI + '/test');

    doc.close(SaveOptions.DONOTSAVECHANGES);
    var movedDocFile = moveFileByCopyDelete(docFile, folder);
    app.open(movedDocFile);

})();

/**
 * Copies a file to a given folder,
 * and removes the original, returning
 * a new reference to the copy.
 * Notes:
 * - This function is a poor workaround
 *   for the lack of a proper MOVE command.
 * - You will lose file metadata such as
 *   created/modified dates.
 * - The original `file` reference will be
 *   invalid after the move, but you can
 *   update it using the returned file.
 * @7111211 m1b
 * @version 2023-08-20
 * @9397041 {File} file - the file to move.
 * @9397041 {Folder} folder - the destination folder.
 * @Returns {File} the moved file.
 */
function moveFileByCopyDelete(file, folder) {

    if (!file || !folder)
        return;

    if (file.constructor.name == 'String')
        file = File(file);

    if (folder.constructor.name == 'String')
        folder = Folder(folder);

    if (!folder.exists)
        folder.create();

    if (!file.exists || !folder.exists)
        return;

    var fileCopy = File(folder.absoluteURI + '/' + file.name);
    file.copy(fileCopy);

    if (fileCopy.exists)
        file.remove();

    return fileCopy;

};
Correct answer Disposition_Dev

on mac you should be able to do it without applescript, by just using shell scripts instead.

write the shell script commands to a file, then execute the file with File.execute();

youd need to premake a .sh file and give it execute permissions though. but then you can just update the contents of that file dynamically with a script and then execute it.

3 replies

jduncan
Community Expert
Community Expert
August 23, 2023

I only had a few minutes to mess with this and it's awefully hacky but it works for Mac and keeps file details intact. You could obviously roll this into one function and check the OS type `var sysOS = /mac/i.test(os) ? "mac" : "win"` to determine the required steps. Hopefully this helps.

 

First you'll need to create a script file, and change the permissions to executable.

$ touch mac_move_file.sh
$ chmod +x mac_move_file.sh

 You'll also need to update the `shellScript` varaible in the JSX file.

(function () {
  // WARNING: do not run with an
  // important document open!

  // Example: takes the active document
  // and moves it into a "test" folder
  // created in its current folder
  var doc = app.activeDocument,
    docFile = doc.fullName,
    folder = Folder(docFile.parent.absoluteURI + "/test");

  var movedDocFile = moveFileByCopyDeleteForMac(docFile, folder);
  $.sleep(2000);
  app.open(movedDocFile);
  alert("File Moved:\n" + movedDocFile);
})();

function moveFileByCopyDeleteForMac(file, folder) {
  shellScript = new File("/Users/jbd/Desktop/mac_move_file.sh");

  if (!file || !folder) return;

  if (file.constructor.name == "String") file = File(file);

  if (folder.constructor.name == "String") folder = Folder(folder);

  if (!folder.exists) folder.create();

  if (!file.exists || !folder.exists) return;

  var fileCopy = File(folder.absoluteURI + "/" + file.name);

  command = "mv " + file + " " + fileCopy;
  writeTextFile(shellScript, command);
  shellScript.execute();

  return fileCopy;
}

function writeTextFile(file, data) {
  try {
    file.encoding = "UTF-8";
    file.open("w");
    file.write(data);
    file.close();
  } catch (e) {
    alert("Error writing file!\n" + e);
  }
}

 

m1b
Community Expert
m1bCommunity ExpertAuthor
Community Expert
August 23, 2023

Thanks @jduncan, when I get a chance I'll try it out. I'm especially interested in whether this method is portable in the sense that I can package up the script, along with the executable shell script and give it to someone else and they can run it without problem. I'm wondering if MacOS will revoke executable status when downloaded from the internet by someone else. I might PM to test if you don't mind. Or feel free to do the same if you have a version ready to test.

- Mark

jduncan
Community Expert
Community Expert
August 24, 2023

It's definitely not portable. I just thought maybe you can use the clipboard trick I've seen on here to copy the path to the clipboard and then run a AppleScript file which is portable. I'll work on this idea in a bit and let you know if I can make it work.

m1b
Community Expert
m1bCommunity ExpertAuthor
Community Expert
August 23, 2023

Of course! Thanks heaps @CarlosCanto and @Disposition_Dev. Exactly what I needed. I'll fix that up and post a function when I get the chance. - Mark

CarlosCanto
Community Expert
Community Expert
August 23, 2023

Hi, using the OS file system keeps file dates, here's how to do it with vbs, applescript should have something similar. So the idea is to write the below vbs file on the fly with jsx and execute it

 

Set fso = CreateObject("Scripting.FileSystemObject")

f = "C:\files\csaw.txt"
d = "C:\files\temp\csaw.txt"

If FileExists(f) = true Then
  WScript.Echo "Does Exist"
	fso.MoveFile f, d
Else
  WScript.Echo "Does not exist"
End If

Function FileExists(FilePath)
  
  If fso.FileExists(FilePath) Then 
    FileExists=CBool(1)
  Else
    FileExists=CBool(0)
  End If
End Function

 

Disposition_Dev
Disposition_DevCorrect answer
Legend
August 23, 2023

on mac you should be able to do it without applescript, by just using shell scripts instead.

write the shell script commands to a file, then execute the file with File.execute();

youd need to premake a .sh file and give it execute permissions though. but then you can just update the contents of that file dynamically with a script and then execute it.