3

I would like to shuffle the pages of a pdf document in a random order.

How can this be done?

3

With pdftk and GNU coreutils

Determine the number of pages in the PDF file, then call shuf to generate a randomized list of page numbers, and call pdftk again to extract the given sequence of pages.

pdftk original.pdf cat $(shuf 1-$(pdftk original.pdf dump_data | awk '$1=="NumberOfPages:" {print $2}')) output randomized.pdf

With Python and PyPdf

#!/usr/bin/env python2
import random, sys
from pyPdf import PdfFileWriter, PdfFileReader
input = PdfFileReader(sys.stdin)
output = PdfFileWriter()
pages = range(input.getNumPages())
random.shuffle(pages)
for i in pages:
     output.addPage(input.getPage(i))
output.write(sys.stdout)'

Usage: /path/to/script <original.pdf >randomized.pdf

  • Where did pdftk go? It's not in the Ubuntu repo anymore. – Ondra Žižka May 25 '18 at 2:02
  • 1
    @OndraŽižka It got dropped from bionic due to library mishaps but should be back in cosmic since it's still in Debian. See askubuntu.com/questions/1029450/… for how to install it on bionic. – Gilles May 25 '18 at 8:38
3

We will use pdftk to perform operations on the pdf document.

  1. Create a temporary working directory:

    mkdir tmp
    
  2. Split the pdf document in many one page documents:

    pdftk original.pdf burst output tmp/pg_%02d.pdf
    
  3. Rename the one-page document with random names:

    for name in tmp/*.pdf; do
       mv "tmp/$name" tmp/$(echo "$name" | sha1sum | cut -f1 -d' ').pdf
    done
    
  4. Merge all the one page documents:

    pdftk tmp/*.pdf cat output random.pdf
    
  5. Clean the temporary working directory:

    rm -r tmp
    
2

a little improvement to Gilles answer:

pdftk original.pdf cat $(shuf --input-range=1-$(pdftk original.pdf dump_data | awk '$1=="NumberOfPages:" {print $2}')) output randomized.pdf
0

There is also a version using pdfjoin/pdfjam (like here) by shuffling the sequence of page numbers and using that as input for pdfjoin:

# $1: source pdf file
# $2: last page number to consider
# $3: name of output file

for k in $(seq 1 $2 | shuf); do
    PAGES+=($1);
    PAGES+=($k);
done

pdfjoin ${PAGES[@]} --outfile $3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.