How to Write a Backslash in AppleScript

I want to do this from the shell with an Apple Script:

/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/MacOS/join -o output inpath1 inpath2

However I don’t know how to write backslash without it raising an error.

This works but only adds the empty spaces:

do shell script "/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/MacOS/join -o output " & inpath1 & "\ " & inpath2

Note: It seems what I write in this post is not what it’s shown. Here is the image:

Any thoughts?

There are three options:

  1. Escape every backslash with another backslash.

    do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/MacOS/join -o output " & inpath1 & "\\ " & inpath2
    
  2. Wrap each path in single quotes

    do shell script "'/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/MacOS/join' -o output '" & inpath1 & "' '" & inpath2 & "'"
    
  3. (Recommended) Use quoted form of. It chooses always the best way to escape the paths

    do shell script quoted form of ("/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/MacOS/join") & space & "-o output" & space & quoted form of inpath1 & space & quoted form of inpath2
    

It’s good practice to use quoted form for any POSIX path in do shell script lines regardless whether they contain special characters or not.

As I understand it, it’s not about the quoting of the pass, but that it shouldn’t work at all.

Firstly, because there is no such JOIN action, but there is a Combine PDF Pages action. At least on Catalina OS.

Second, this action is only allowed to be performed by Automator, and then only as part of a bigger workflow or service. How Automator provides the PDFs input to the utility is another big mystery.

And here is how it can be done in the way predefined by the Apple team (using - Automator) - https://www.orbitsit.co.uk/2013/06/combining-pdfs-using-automator

NOTE: instead of Service the user should create Quick Action on new systems. It is just synonym.

I know next to nothing about this topic, but I made a few edits to Stefan’s third suggestion, and it did create the combined PDF on my Ventura computer.

set theOutput to POSIX path of (path to desktop) & "New PDF.pdf"
set inpath1 to "/Volumes/Store/Test/Test One.pdf"
set inpath2 to "/Volumes/Store/Test/Test Two.pdf"

do shell script quoted form of ("/System/Library/Automator/Combine PDF Pages.action/Contents/MacOS/join") & space & "-o" & space & quoted form of theOutput & space & quoted form of inpath1 & space & quoted form of inpath2
2 Likes

Sorry, if I was wrong for the latest OS versions.

On my Catalina join utility doesn’t exist at all in MacOS folder of Combine PDF Pages.action. Instead exists utility named Combine PDF Pages. When I run following:

do shell script (quoted form of “/System/Library/Automator/Combine PDF Pages.action/Contents/MacOS/Combine PDF Pages)”

it returns AppleScript Execution Error:

sh: /System/Library/Automator/Combine PDF Pages.action/Contents/MacOS/Combine PDF Pages: cannot execute binary file

The OP’s question has been answered above, and it seems to work well. FWIW, the following will do the same thing and might be considered in some instances. To test this script, open it in a script editor and run.

use framework "AppKit"
use framework "Foundation"
use framework "Quartz"
use scripting additions

set theInput to (choose file of type {"pdf"} with multiple selections allowed)
set theOutput to POSIX path of (path to desktop) & "Merged PDF Files.pdf"
mergeFiles(theInput, theOutput)

on mergeFiles(theInput, theOutput) -- a minor rewrite of a handler by Shane
	set theInput to current application's NSArray's arrayWithArray:theInput
	set theInputCount to theInput's |count|()
	set theOutput to current application's |NSURL|'s fileURLWithPath:theOutput
	set outDoc to current application's PDFDocument's alloc()'s initWithURL:(theInput's objectAtIndex:0)
	set outDocPageCount to outDoc's pageCount()
	repeat with i from 1 to (theInputCount - 1)
		set aDoc to (current application's PDFDocument's alloc()'s initWithURL:(theInput's objectAtIndex:i))
		set aDocPageCount to aDoc's pageCount()
		repeat with j from 0 to (aDocPageCount - 1)
			(outDoc's insertPage:(aDoc's pageAtIndex:j) atIndex:outDocPageCount)
			set outDocPageCount to outDocPageCount + 1
		end repeat
	end repeat
	outDoc's writeToURL:theOutput
end mergeFiles
1 Like

Information for Catalina users.

Oh my God! I finally found this join utility, which turned out to be the join.py Python script in Catalina. And which is also in the Resources subfolder instead of MacOS.

Wow! It combined 2 PDFs, but it was deadly slow (2 min 31 seconds):

set theOutput to quoted form of (POSIX path of (path to desktop) & "New PDF.pdf")
set inpath1 to quoted form of (POSIX path of (choose file of type "com.adobe.pdf"))
set inpath2 to quoted form of (POSIX path of (choose file of type "com.adobe.pdf"))
set joinPath to quoted form of ("/System/Library/Automator/Combine PDF Pages.action/Contents/Resources/join.py")

do shell script joinPath & " -o " & theOutput & space & inpath1 & space & inpath2

So, the AsObjC solution from @peavine is clearly preferable. At least on Catalina.

Several years ago I tried using the join.py Python script to merge PDF files and, as KniazidisR points out, it is terribly slow. The join utility in the MacOS subfolder on Ventura is a Unix executable and in my testing is only marginally slower than the ASObjC solution.

It’s possible the join utility is available in versions of macOS prior to Ventura, and this can be tested by running the following script in a script editor.

set inputFiles to (choose file of type "com.adobe.pdf" with multiple selections allowed)
mergePdfFiles(inputFiles)

on mergePdfFiles(inputFiles)
	set inputFilesString to ""
	repeat with aFile in inputFiles
		set inputFilesString to inputFilesString & (quoted form of POSIX path of aFile) & space
	end repeat
	set outputFile to quoted form of (POSIX path of (path to desktop) & "Merged PDF Files.pdf")
	set joinUtility to quoted form of "/System/Library/Automator/Combine PDF Pages.action/Contents/MacOS/join"
	do shell script joinUtility & " -o " & outputFile & space & inputFilesString
end mergePdfFiles

Didn’t work for me. I’m using Ventura MacOS

For me it wasn’t slow. It took seconds with @peavine solution.

Thank you so much! Worked perfectly :slight_smile: BTW, what is the best way to learn AppleScript in your opinion? Can you point me to some resources?

The best approach to learn basic AppleScript IMO is to begin writing simple scripts; to ask for assistance in this forum when you get stuck; and to follow some of the threads in this forum that interest you. As a reference work, the AppleScript Language Guide is excellent:

Many users who are new to AppleScript find it useful to utilize shell commands, which they may already be familiar with. If that’s the case, the following document (although a bit dated) can be very helpful:

I forgot a double quote after join. Post edited.