1

I have a Perl script that does some text transformation on a given file.

Now I would like to call this script from an AppleScript which in turn I could execute from the script menu in order to run the Perl script on a set of files with a choose folder prompt. My Perl script starts like this:

open my $in, '<', 'myfile.txt' or die "No input: $!";
open my $out, '>', 'myfile-modified.txt';

And then it does a bunch of search-and-replace and what not.

I would like to somehow call this script from an AppleScript and process multiple files. The AppleScript should look more or less like this:

set myFolder to choose folder with prompt "Choose a folder:"
tell application "Finder"
    try
        set myFiles to (every file in entire contents of myFolder whose name ends with ".txt") as alias list
    on error
        try
            set myFiles to ((every file in entire contents of myFolder whose name ends with ".txt") as alias) as list
        on error
            set myFiles to {}
            display dialog "No files in folder."
        end try
    end try
end tell

How can I run the Perl script from AppleScript while passing myFiles as a variable to it (the perl script) and looping through them? I assume I have to do a do shell script command but I don't know how to pass the variables on.

I also don't know whether it'd be better to pass the files as a file list to perl or to somehow put that into a repeat loop within AppleScript?

2 Answers 2

1

The maximum length of a command line is 2**18 bytes:

$ getconf ARG_MAX
262144

So that for example this results in an error:

read "/usr/share/dict/web2" for 270000
do shell script "printf %s " & quoted form of result

If the input is short enough, you can pass it to perl as part of the command line:

read "/usr/share/dict/web2" for 260000
do shell script "printf %s\\\\n " & quoted form of result & "|perl -pe'$_=uc'"

Otherwise you can use a temporary file:

set input to read "/usr/share/dict/web2" for 270000
set f to (system attribute "TMPDIR") & "my.tempfile"
set fd to open for access f with write permission
set eof fd to 0
write input to fd as «class utf8»
close access fd
do shell script "perl -pe'$_=uc' " & f & ";rm " & f

The default text encoding is still an encoding like MacRoman or MacJapanese, so that adding as «class utf8» to the write command preserves non-ASCII characters, even though it is not necessary in the example above.

In your case you could also do something like this:

quoted form of POSIX path of (choose folder)
do shell script "find " & result & " -name \\*.txt|perl -pe'$_=uc'"

quoted form of escapes text for shells, so that it replaces ' with '\'' and surrounds text with single quotes.

1
  • Thank you for this! May I ask you to expand a bit? I will need the longer version for sure since my perl script is rather complex. But how do I call it (i.e., where do I put the path to the perl script)? And how can I modify the script in order to recognize the input? (what to put instead of "myfile.txt" in the perl script itself?) I'm sorry if this is obvious to a more experienced user, but I'm not very well versed in either applescript or perl ...
    – jan
    May 14, 2016 at 5:45
1

I finally figured it out:
I can achieve what I want by using the $ARGV array which holds all arguments that are passed on to the perl script via the command line. In an applescript I can simply put this line:

do shell script "perl myscript.pl inputfile outputfile"

Assuming inputfile and ouputfile are the (paths to) the files I want to run the perl script on. I then call inputfile with $ARGV[0] (the first argument passed on) and outputfile with $ARGV[1] (the second argument).

open my $fh_in, '<', $ARGV[0] or die "No input: $!";
open my $fh_out, '>', $ARGV[1] or die "No output: $!";

Hope this will be useful to someone.

5
  • The key part of your answer should be clearly stated:•• return •• You have to place the arguments on the line of calling the needed shell script exactly as they would be used on the command line perl myscript.pl arg1 arg2 ....
    – dan
    May 21, 2016 at 14:05
  • @danielAzuelos I've modified it a bit, I hope it's clearer now. But please, go ahead and edit it if you feel necessary so that it'll be usable for posteriority. I'm not an expert on this at all so any hints how to put it into the right words are very welcome.
    – jan
    May 21, 2016 at 14:18
  • 1
    It is clearer :).
    – dan
    May 21, 2016 at 16:00
  • @danielAzuelos Quick question: Is it considered bad practice to mark one's own answer as the correct answer? Since someone else has answered already although that answer wasn't quite what I was looking for. (just to not have it show up as "unanswered")
    – jan
    May 21, 2016 at 16:05
  • 1
    Perfectly OK if you are satisfied with it. Most of the time the good searcher is the one who find. The other answer isn't really usefull.
    – dan
    May 21, 2016 at 16:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .