Split PDF Script

This script allows you to split a PDF file into a specified number of parts. It takes an input PDF file and the desired number of parts, calculates the page range for each part, and generates separate output files for each part.

1. What It Does

split-pdf.sh Processing Steps Validate argsfile + partsBase namebasename .pdfCount pagespdftk dump_dataCompute rangespages / partspdftk catone file per rangeIf any pdftk call fails the script prints an error and exits with status 1.

Large PDFs are awkward for document-ingestion pipelines: upload limits, LLM context windows, OCR timeouts and parallel processing all work better on smaller files. This script splits one PDF into a chosen number of roughly equal parts using pdftk, a long-standing command-line PDF toolkit. It does not re-render or recompress pages; pdftk cat copies page objects into new files, so text, images and fonts are preserved exactly and the split is fast.


2. Installation Requirements

Before running the script, make sure to install pdftk on Ubuntu by running the following commands:

sudo apt-get update
sudo apt-get install -y pdftk

3. Usage

To run the script, use the following command:

./split-pdf.sh input_file number_of_parts

Replace input_file with the path to your PDF file, and number_of_parts with the number of parts you want to split the file into. For example:

./split-pdf.sh document.pdf 3

This command will split document.pdf into 3 separate PDF files.

4. How the Script Works

The script performs the following steps:

  1. Extracts the base name from the input file (removing the path and extension).
  2. Uses pdftk to determine the total number of pages in the PDF.
  3. Calculates the number of pages per part by dividing the total pages by the number of parts specified.
  4. Splits the PDF into the specified number of parts, creating output files named with the base name followed by a part number (e.g., document-1.pdf, document-2.pdf).

5. split-pdf.sh

#!/bin/bash

# Installation Requirements on Ubuntu:
# sudo apt-get update
# sudo apt-get install -y pdftk

# Usage: ./split-pdf.sh input_file number_of_parts

# Input Arguments
input_file="$1"
number_of_parts="$2"

# Check if correct arguments are passed
if [[ -z "$input_file" || -z "$number_of_parts" ]]; then
  echo "Usage: $0 input_file number_of_parts"
  exit 1
fi

# Extract base name from input file (remove path and extension)
base_name=$(basename "$input_file" .pdf)

# Find the number of pages in the PDF
total_pages=$(pdftk "$input_file" dump_data | grep NumberOfPages | awk '{print $2}')

if [[ -z "$total_pages" ]]; then
  echo "Error: Could not determine the number of pages in the PDF."
  exit 1
fi

# Calculate the number of pages per part
pages_per_part=$((total_pages / number_of_parts))
remainder=$((total_pages % number_of_parts))

start_page=1

# Split the PDF file into the specified number of parts
for ((i=1; i<=number_of_parts; i++)); do
  if [[ $i -eq $number_of_parts ]]; then
    end_page=$total_pages
  else
    end_page=$((start_page + pages_per_part - 1))
  fi

  output_file="${base_name}-${i}.pdf"

  pdftk "$input_file" cat ${start_page}-${end_page} output "$output_file"

  if [[ $? -eq 0 ]]; then
    echo "Generated: $output_file"
  else
    echo "Error creating: $output_file"
    exit 1
  fi

  start_page=$((end_page + 1))

done

6. Page Range Math

Page Range Calculation for a 10-Page PDF in 3 Parts pages 1-3document-1.pdfpages 4-6document-2.pdfpages 7-10document-3.pdftotal_pages = 10, number_of_parts = 3pages_per_part = 10 / 3 = 3 (integer division), remainder = 1Parts 1..n-1 get exactly pages_per_part pages; the last part (yellow) runs to total_pagesand absorbs the remainder, so it can be up to number_of_parts - 1 pages longer.

The script uses Bash integer arithmetic. $((total_pages / number_of_parts)) truncates, so with 10 pages and 3 parts each part gets 3 pages and one page is left over. Rather than distributing the remainder, the loop simply lets the final part end at total_pages. The remainder variable is computed but not otherwise used. The variable start_page advances to end_page + 1 after each part, so ranges never overlap and no page is skipped.

7. The Code Explained

8. Usage Examples

chmod +x split-pdf.sh

# Split a 300-page manual into 6 files of 50 pages
./split-pdf.sh manual.pdf 6

# Split every PDF in a folder into 4 parts each
for f in reports/*.pdf; do ./split-pdf.sh "$f" 4; done

# Check the result
for f in manual-*.pdf; do
  echo "$f: $(pdftk "$f" dump_data | awk '/NumberOfPages/ {print $2}') pages"
done

If pdftk is unavailable, qpdf does the same job: qpdf in.pdf --pages . 1-50 -- part-1.pdf.

9. Python Alternative

Inside a Python ingestion pipeline it is often simpler to split with the pypdf library and distribute the remainder evenly:

from pathlib import Path
from pypdf import PdfReader, PdfWriter   # pip install pypdf

def split_pdf(path, parts):
    reader = PdfReader(path)
    n = len(reader.pages)
    base, extra = divmod(n, parts)
    start, stem = 0, Path(path).stem
    for i in range(parts):
        size = base + (1 if i < extra else 0)   # spread the remainder
        writer = PdfWriter()
        for p in range(start, start + size):
            writer.add_page(reader.pages[p])
        out = f"{stem}-{i + 1}.pdf"
        with open(out, "wb") as fh:
            writer.write(fh)
        print("Generated:", out, f"pages {start + 1}-{start + size}")
        start += size

split_pdf("document.pdf", 3)   # 4, 3, 3 pages

10. Pitfalls

11. Why Split PDFs for Ingestion

In document-ingestion work the split is rarely the goal in itself; it is a preparation step that makes later stages manageable. Typical reasons are:

Because the script names parts sequentially and keeps original page order, the parts can be merged back with pdftk name-*.pdf cat output merged.pdf (with care for shell sort order when there are ten or more parts; use zero-padded numbers in that case). When the output feeds a retrieval system, record the original page offsets for each part so that answers can cite the page number in the source document, not in the fragment.