I have an automator service that I was updating to handle a series of input files in combination (instead of serially, like it currently does). It does a bunch of stuff, but in one component of it, I need to process the contents of N files and hand the processing of the output of each file off to a single paste
command to combine it all and further process the combo. On the command line, I would do it with process substitution, e.g.:
paste <(commands processing file 1) <(commands processing file 2) ... | other processing commands
But if I do this from inside an applescript, like this:
set output to (do shell script "paste <(commands processing file 1) <(commands processing file 2) ... | other processing commands")
I get an error from applescript:
The action “Run AppleScript” encountered an error: “Finder got an error: sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `paste <(commands processing file 1) <(commands processing file 2) ... | other processing commands'”
I learned that this is because sh
doesn't do the fancy stuff that bash does, e.g. process substitution.
I know I could just write temporary files to accomplish my goal, but I'd rather not have to if there's a way around it.
I tried getting around this by using bash -s
:
set output to (do shell script "bash -s <<'EOF'" & return & "paste <(commands processing file 1) <(commands processing file 2) | other processing commands" & return & "EOF")
But that yields the same error.
Any idea how to accomplish this without having to write temporary files?
UPDATE: I realized that I pared the problem down too much. There is a bit more to it. The series of commands I am using (including the paste
command mentioned already), includes one-liner code that contains variables and single-quotes, so the solution would need have to prevent shell interpolation of variables and not interfere with single-quotes. I will update the toy example below to include those details.
Toy example (applescript):
file 1:
this is the first test
file 2:
this is the second test
applescript:
set file1 to "~/file1.txt"
set file2 to "~/file2.txt"
set output to (do shell script "paste <(head " & file1 & " | perl -ne 'chomp;print(substr($_,0,4),qq(\\n))') <(head " & file2 & " | perl -ne 'chomp;print(substr($_,-4),qq(\\n))')"
display dialog output
Expected output:
this test
Note, there are other variables and another command (awk) using single quotes.
Oh my gosh! Right after I posted this, I realized that all I needed to do was escape the parens. I was on the right track with bash -s
! I think writing out the question was just the process I had to go through to realize the answer!
set output to (do shell script "bash -s <<'EOF'" & return & "paste \\<\\(commands processing file 1\\) \\<\\(commands processing file 2\\) | other processing commands" & return & "EOF")
I can't believe I didn't see it before posting the question!