1

I have a folder containing hundreds of PDFs, and I would like to remove the last page of each one in a quick way. How can I let my Mac automate this task? Do I need additional software to do this?

1

I've done this using the Coherent PDF Command Line Tools Community Release.

You can download either the pre-built tools or the source code to compile the later on your own, however the latter requires OCaml be installed when compiling. So the pre-built tools are the easiest way to go. The downloaded distribution file, e.g. cpdf-binaries-master.zip, contains binaries for Linux, OS X/macOS and Windows and is ~5 MB in size.

Once downloaded and extracted (double-clicking the .zip file) you'd copy the, e.g. ~/Downloads/cpdf-binaries-master/OSX-Intel/cpdf, file to a location that is defined in the PATH environment variable, e.g. /usr/local/bin/ to make it globally available on the command line in Terminal. If it's not in the PATH then you'll have to use the fully qualified pathname to the cpdf executable or ./cpdf if it's in the present working directory (pwd). In Terminal, type echo $PATHso show the PATH.

The syntax for removing the last page when the PDF file has 3 or more pages is:

cpdf in.pdf 1-~2 -o out.pdf

The syntax for removing the last page when the PDF file has 2 pages is:

cpdf in.pdf 1 -o out.pdf

Because cpdf reads the original file (in.pdf) and writes to a new file (out.pdf) the out.pdf filename needs to be different if saved to the same location as the in.pdf file, or save it to a different location with the same in.pdf filename as the out.pdf filename, or whatever out.pdf filename you want.

Below, I'll show two examples of automation using cpdf to remove the last page of a PDF file, assuming it has two or more pages. One using an Automator workflow as a Service available in Finder on the Services Context Menu and the other as a bash script, to use in Terminal.


As an Automator Service Workflow available in Finder on the Services Context Menu:


In Automator create a new service workflow using the settings as shown in the image below and copy and paste the code below the image into the Run Shell Script action and save as e.g.: Remove Last Page from PDF

To use Remove Last Page from PDF, in Finder select the PDF files you want to remove the last page from and then select Remove Last Page from PDF from the Context Menu via right-click or control-click, or from Finder > Services > Remove Last Page from PDF

Automator Service Workflow


for f in "$@"; do
        # Get Page Count.
    p="$(/usr/local/bin/cpdf -info "$f" | awk '/Pages:/{print $2}')"
        # Get file extension.
    ext="${f##*.}"
        # Get filename without extension.
    fn="${f%.*}"
        # Rename original file to "filename (original).pdf".
        # Use '-n' to not overwrite an existing file.
    mv -n "$f" "${fn} (original).${ext}"
        # If page count is greater than 2, set 'p' to '3' as any
        # PDF with more than 2 pages the command will be the same.
    if [[ $p -gt 2 ]]; then
        p="3"
    fi
    case "$p" in
        3)
                # PDF file has 3 or more pages.
            /usr/local/bin/cpdf "${fn} (original).${ext}" 1-~2 -o "$f" 
            ;;
        2)
                # PDF file has 2 pages.
            /usr/local/bin/cpdf "${fn} (original).${ext}" 1 -o "$f"
            ;;
        1)
                # PDF file has 1 page. Make a copy to the
                # original name for consistency of output.
                # Use '-n' to not overwrite an existing file.
            cp -n "${fn} (original).${ext}" "$f"
            ;;      
    esac
        # If you don't want to keep the original
        # file, remove '#' from the next line.
    # rm "${fn} (original).${ext}"
done

Note that the PATH passed a Run Shell Script action in Automator is, /usr/bin:/bin:/usr/sbin:/sbin. So the code above is using the fully qualified pathname to the cpdf executable, /usr/local/bin/cpdf as that is where I placed it so as to be available in Terminal by way of using its name cpdf, only.

Also note that if you do not want to keep the original files, then uncomment (remove the # from in front of) the # rm "${fn} (original).${ext}" command, just above the last line of code done.



As a bash script to use in Terminal:


Create the bash script in the following manner:

In Terminal:

touch rlpfpdf
open rlpfpdf

Copy the code block, starting with #!/bin/bash, below into the opened rlpfpdf document and then save it.

Back in Terminal:

Make the script executable:

chmod u+x rlpfpdf

Now move the rlpfpdf script to, e.g.: /usr/local/bin/

sudo mv rlpfpdf /usr/local/bin/

You can then change directory cd ... to a directory that has the PDF files that you want to remove the last page from and then simply type rlpfpdf and press enter.

The original files will be moved to "filename (original).pdf" and the newly create PDF file sans the last page, if 2 or more pages, will have the original filename.pdf name.


#!/bin/bash

for f in *.pdf *.PDF; do
    if [[ -f $f ]]; then
            # Get Page Count.
        p="$(cpdf -info "$f" | awk '/Pages:/{print $2}')"
            # Get file extension.
        ext="${f##*.}"
            # Get filename without extension.
        fn="${f%.*}"
            # Rename original file to "filename (original).pdf".
            # Use '-n' to not overwrite an existing file.
        mv -n "$f" "${fn} (original).${ext}"
            # If page count is greater than 2, set 'p' to '3' as any
            # PDF with more than 2 pages the command will be the same.
        if [[ $p -gt 2 ]]; then
            p="3"
        fi
        case "$p" in
            3)
                    # PDF file has 3 or more pages.
                cpdf "${fn} (original).${ext}" 1-~2 -o "$f" 
                ;;
            2)
                    # PDF file has 2 pages.
                cpdf "${fn} (original).${ext}" 1 -o "$f"
                ;;
            1)
                    # PDF file has 1 page. Make a copy to the
                    # original name for consistency of output.
                    # Use '-n' to not overwrite an existing file.
                cp -n "${fn} (original).${ext}" "$f"
                ;;      
        esac
            # If you don't want to keep the original
            #  file, remove '#' from the next line.
        # rm "${fn} (original).${ext}"
    fi
done

Note that the code above assumes the cpdf executable is in a directory that is within the PATH environment variable, e.g.: /usr/local/bin/

Also note that if you do not want to keep the original files, then uncomment (remove the # from in front of) the # rm "${fn} (original).${ext}" command, just above the last line of code done.

| improve this answer | |
  • I just have 1 simple inquiry. How can I modify the code block to remove the first page instead of the last? – InterestedLearner Feb 23 '17 at 16:32
  • @InterestedLearner, Within the downloaded distribution file, e.g. cpdf-binaries-master.zip, there is the cpdfmanual.pdf file and under "1.2 Input Ranges", starting on page 2, it discusses this. The syntax to remove the first page is cpdf in.pdf 2-end out.pdf The code provided in my answer to your OP is specific to removing the last page and you can't just simply use 2-end in place of 1-~2 or 1 within the script as it's written. You'd have to recode it to match the conditions. If you post a new question I'll post a script that's conducive to the conditions. – user3439894 Feb 23 '17 at 17:01
  • Hey, @user3439894, very nice response. The syntax cpdf in.pdf 1-~2 -o out.pdf now works for 2-page documents as well. It'd be great if you could edit your answer accordingly. This will simplify the script a lot. – retrography May 29 '19 at 11:36

You must log in to answer this question.

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