Автоматизируйте удаление последней страницы из множества PDF-файлов

У меня есть папка, содержащая сотни PDF-файлов, и я хотел бы быстро удалить последнюю страницу каждого из них. Как я могу позволить моему Mac автоматизировать эту задачу? Нужно ли для этого дополнительное программное обеспечение?

Ответы (1)

Я сделал это с помощью Coherent PDF Command Line Tools Community Release .

Вы можете загрузить либо готовые инструменты, либо исходный код , чтобы скомпилировать его самостоятельно, однако последний требует установки OCaml при компиляции. Таким образом, готовые инструменты — самый простой способ. Загруженный файл дистрибутива, например, cpdf-binaries-master.zip , содержит двоичные файлы для Linux, OS X/macOS и Windows и имеет размер ~5 МБ.

После загрузки и извлечения (двойной щелчок по файлу .zip) вы скопируете, например, ~/Downloads/cpdf-binaries-master/OSX-Intel/cpdf файл в место, указанное в PATH переменной среды , например, /usr/local/bin/в сделать его глобально доступным в командной строке терминала. Если его нет в PATH, вам придется использовать полный путь к cpdfисполняемому файлу или ./cpdfесли он находится в текущем рабочем каталоге ( pwd). В Терминале введите echo $PATHтак, чтобы показать файл PATH.

Синтаксис для удаления последней страницы, когда файл PDF содержит 3 или более страниц :

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

Синтаксис для удаления последней страницы , когда файл PDF имеет 2 страницы:

cpdf in.pdf 1 -o out.pdf

Поскольку cpdfпри чтении исходного файла ( in.pdf ) и записи в новый файл ( out.pdf ) имя файла out.pdf должно быть другим, если оно сохраняется в том же месте, что и файл in.pdf , или сохраняется в другом месте. с тем же именем файла in.pdf , что и имя файла out.pdf , или любым другим именем файла out.pdf , которое вы хотите.

Ниже я покажу два примера использования автоматизации cpdfдля удаления последней страницы PDF-файла, если в нем две или более страниц. Один использует рабочий процесс Automator в качестве службы , доступной в Finder в контекстном меню служб , а другой — в качестве сценария для использования в терминале.bash


Как рабочий процесс службы Automator, доступный в Finder в контекстном меню служб:


В Automator создайте новый рабочий процесс службы , используя настройки, как показано на изображении ниже, скопируйте и вставьте код под изображением в действие «Выполнить сценарий оболочки» и сохраните его, например: «Удалить последнюю страницу из PDF».

Чтобы использовать «Удалить последнюю страницу из PDF» , в Finder выберите PDF-файлы, из которых вы хотите удалить последнюю страницу, а затем выберите « Удалить последнюю страницу из PDF» в контекстном меню , щелкнув правой кнопкой мыши или удерживая нажатой клавишу «Control» , либо в Finder > «Службы» > «Удалить» . Последняя страница из PDF

Рабочий процесс службы автоматизации


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

Обратите внимание, что PATHпереданное действие Run Shell Script в Automator — это . Таким образом, приведенный выше код использует полное имя пути к исполняемому файлу , так как я поместил его туда, чтобы он был доступен в Терминале только с помощью его имени ./usr/bin:/bin:/usr/sbin:/sbincpdf /usr/local/bin/cpdfcpdf

Также обратите внимание, что если вы не хотите сохранять исходные файлы, раскомментируйте (удалите #перед) # rm "${fn} (original).${ext}" команду прямо над последней строкой кода done .



Как bash скрипт для использования в Терминале:


Создайте bash скрипт следующим образом:

В терминале:

touch rlpfpdf
open rlpfpdf

Скопируйте приведенный ниже блок кода , начинающийся с #!/bin/bash, в открытый rlpfpdfдокумент и сохраните его.

Снова в Терминале:

Сделайте скрипт исполняемым:

chmod u+x rlpfpdf

Теперь переместите rlpfpdf скрипт , например:/usr/local/bin/

sudo mv rlpfpdf /usr/local/bin/

Затем вы можете изменить каталог cd ...на каталог с файлами PDF, из которых вы хотите удалить последнюю страницу, а затем просто введите rlpfpdfи нажмите enter.

Исходные файлы будут перемещены в « имя файла (оригинал).pdf », а вновь созданный файл PDF без последней страницы, если 2 или более страниц, будет иметь исходное filename.pdfимя.


#!/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

Обратите внимание, что приведенный выше код предполагает, что cpdf исполняемый файл находится в каталоге , который находится в PATH переменной среды , например:/usr/local/bin/

Также обратите внимание, что если вы не хотите сохранять исходные файлы, раскомментируйте (удалите #перед) # rm "${fn} (original).${ext}" команду прямо над последней строкой кода done .

У меня есть только 1 простой запрос. Как я могу изменить блок кода, чтобы удалить первую страницу вместо последней?
@InterestedLearner, в загруженном файле дистрибутива, например cpdf-binaries-master.zip , есть файл cpdfmanual.pdf , и в разделе «1.2 Диапазоны ввода», начиная со страницы 2, это обсуждается. Синтаксис для удаления первой страницы: cpdf in.pdf 2-end out.pdfКод , представленный в моем ответе на ваш OP, специфичен для удаления последней страницы, и вы не можете просто использовать его вместо или внутри сценария , как он написан. Вам придется перекодировать его, чтобы он соответствовал условиям. Если вы разместите новый вопрос, я опубликую сценарий , который соответствует условиям. 2-end1-~21
Привет, @user3439894, очень хороший ответ. Синтаксис cpdf in.pdf 1-~2 -o out.pdfтеперь работает и для 2-страничных документов. Было бы здорово, если бы вы могли соответствующим образом отредактировать свой ответ. Это значительно упростит сценарий.