Can Scriptable recursively search bookmarked folders (and subfolders) for files?

Looking at the Scriptable documentation it doesn’t looks like FileManager has any inherent means of searching. Is that right? Or am I missing something? (I suppose the current methods could be used to implement something, but I imagine it would be very inefficient.)

My use case: I’d like to find all files in a bookmarked Folder (or, more precisely, inside sub-sub-folders of the bookmarked Folder) that have a certain tag applied to them.

As far as I know there is no API for searching. I’m afraid it looks like you have to do it on your own…

But why should it be inefficient? Searching means to go over each file and checking if it meets the requirements as far as know.

I think if there was an API for that it would probably be quite complex to support every combination. Or it would just be a wrapper around iterating over each file while calling a user provided callback function.

There is no API for searching for files but you can list all files and folders in a directory and it should be fairly easily to do this recursively. Then for each file you can check if it matches your criteria.

I could add an API to search a folder and I might do so in the future but it’s really a matter of finding the right balance between implementing specific APIs and giving developers the right building blocks to create awesome this themselves :blush:

Got it, thanks.

I’m happy to build the script to do what I want, I just didn’t want to do it if there was some better way already lurking inside Scriptable.

Great app!!

1 Like

I’m late to the party here, but I just wrote a util to recursively fetch all files in a directory, sharing below. With this code I’m able to return 13.5K nested files in well under a half second.

const getAllFilesRecursively = rootPath => {
  const fm = FileManager.iCloud();
  const childPaths = fm
    .listContents(rootPath)
    .map(childName => `${rootPath}/${childName}`);
  const { files, directories } = segment(childPaths, {
    files: path => !fm.isDirectory(path),
    directories: 'UNMATCHED',
  });
  return [...files, ...directories.flatMap(getAllFilesRecursively)];
};

segment is a util I wrote to just segment an array by conditions, all it’s doing is splitting the array of all filepaths into filepaths that are files vs. directories.

This could be easily extended to only return files matching certain criteria, or to take action on the files.