Ghostscript gs: Merge and Split PDFs
gs -sDEVICE=pdfwrite -o merged.pdf a.pdf b.pdf concatenates PDFs in order into one file.
Ghostscript merges PDFs by listing inputs after the pdfwrite device and extracts pages with first/last-page flags. It is a dependency-free alternative to pdfunite or qpdf for combining artifacts.
What it does
With -sDEVICE=pdfwrite, Ghostscript writes a single output PDF from every input file you list, in order, effectively concatenating them. -dFirstPage and -dLastPage restrict the output to a page range, which lets you split or extract sections.
Common usage
# merge several PDFs in order
gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dQUIET \
-sOutputFile=merged.pdf a.pdf b.pdf c.pdf
# extract pages 2-5 into a new PDF
gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH \
-dFirstPage=2 -dLastPage=5 \
-sOutputFile=pages2-5.pdf in.pdfOptions
| Flag | What it does |
|---|---|
| -sDEVICE=pdfwrite | Write a PDF |
| -sOutputFile=<f> | Merged/output PDF path |
| a.pdf b.pdf ... | Inputs concatenated in listed order |
| -dFirstPage=<n> | First page to include (for split/extract) |
| -dLastPage=<n> | Last page to include |
| -dNOPAUSE -dBATCH | Non-interactive; exit when done |
In CI
Order matters: inputs are concatenated exactly as listed, so build the file list deterministically (e.g. sort) for reproducible artifacts. Merging through pdfwrite also re-encodes, which can change file size; qpdf preserves bytes more faithfully if that matters.
Common errors in CI
"gs: command not found" means Ghostscript is missing. "Error: /undefinedfilename in (a.pdf)" means an input path is wrong. A merge that drops form fields, annotations, or bookmarks is expected with pdfwrite (it flattens some structure); use qpdf --empty --pages a.pdf b.pdf -- out.pdf if you need to preserve them. Missing -dBATCH makes gs wait after processing and appear to hang.