Finder

Automating Finder

Finder is probably the most-used program on a Mac with a comprehensive scripting dictionary. The examples here illustrate how to get to a file object from a path and how to rename a selection of files or folders using a regular expression.

Get a file object from it’s name #

File is of course one of the central elements of Finder. However, you can’t get a file object directly from its name. Instead, you have to go through System Events and its aliases element:

1
2
3
4
5
const SEApp = Application("System Events");
const finderApp = Application("Finder");
const path = '/Users/myself/path/to/file';
const file = SEApp.aliases(path);
const finderObj = finderApp.items[file.name()];

Once you have a file object in Finder, you can get its properties and for example set its Finder comment with fileObject.comment = 'My comment';.

Batch rename files using Regular Expression #

Similarly to a script for DEVONthink 3, the following code allows the user to batch rename the currently selected files using a regular expression.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(() => {
  const app = Application("Finder");
  app.includeStandardAdditions = true;
  const selection = app.selection();
  if (selection.length > 0) {
    const suffix = selection.length > 1 ? "s" : "";

    /* Set title to display # of selected records */

    const title = 
      `Change name${suffix} for ${selection.length} file${suffix}`;

    /* Ask user for RegExp, stop if empty string */
    const searchFor = app.displayDialog("Search for RE", {
      withTitle: title,
      defaultAnswer: "",
    });
    if (searchFor.textReturned === "") return;

     /* 
      * Ask user for replacement, 
      * showing the RegExp they entered 
      */
    const replaceWith = app.displayDialog(
      `Replace "${searchFor.textReturned}" by: (use $1, $2 etc. for groups)`,
      { withTitle: title, defaultAnswer: "" }
    );
    const re = new RegExp(searchFor.textReturned);
    const reText = replaceWith.textReturned;

    const inform = selection.map(
      (s) => `${s.name()} => ${s.name().replace(re, reText)}`
    );
    app.displayDialog(inform, { withTitle: "Filename to change" });
    selection.forEach((s) => {
      s.name = s.name().replace(re, reText);
    });
  }
})();
About