Applescript with get every file loop fails
I want to run a script on all files with two specific extensions on a disk with a hierarchy of multiple nested folders. My script works fine when I choose a folder further down the line with fewer subfolders but I'd like to run it on an entire archive with over a thousand folders. The AppleScript takes forever to get
all the files and then exits without returning anything and without executing the operations after getting the files. No timeout message, no error message. And the Finder becomes unresponsive (and remains stuck after the script exits).
set myFolder to choose folder with prompt "Choose a folder:"
tell application "Finder"
try
set eafFiles to (every file in entire contents of myFolder whose name ends with ".eaf") as alias list
on error
try
set eafFiles to ((every file in entire contents of myFolder whose name ends with ".eaf") as alias) as list
on error
set eafFiles to {}
end try
end try
try
set pfsxFiles to (every file in entire contents of myFolder whose name ends with ".pfsx") as alias list
on error
try
set pfsxFiles to ((every file in entire contents of myFolder whose name ends with ".pfsx") as alias) as list
on error
set pfsxFiles to {}
end try
end try
set myFiles to eafFiles & pfsxFiles
end tell
repeat with CurrentFile in myFiles
set CurrentFile to CurrentFile as string
do shell script "perl /path/to/perl/script.pl " & quoted form of CurrentFile
end repeat
Solution 1:
Perl's File::Find is ideal for iterating over all the files in a folder. This approach deals with one file at a time, is fast, and memory efficient.
Use AppleScript to present the folder choice and then pass the selected folder path to your perl script:
set myFolder to choose folder with prompt "Choose a folder:"
do shell script "perl /path/to/perl/script.pl " & quoted form of POSIX path of myFolder
The perl script can then deal with traversing the files. Below is sample perl script for iterating over files and filtering to only eaf
and pfsx
suffixes:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
# Get the first argument passed to the script
my $argument_path = shift;
die("ERROR: an argument must be provided\n") unless $argument_path;
die("ERROR: the argument must be a folder: $argument_path\n") unless -d $argument_path;
# Iterate over every file and folder within the $argument_path
find sub {
my $filename = $_; # relative to current working directory
# Skip all but .eaf and .pfsx file types
return unless $filename =~ /\.eaf$/;
return unless $filename =~ /\.pfsx$/;
print $filename."\n";
# ... deal with the file or folder here
}, $argument_path;