Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've got a double-side-printed multipage document to scan with a linear bulk scanner. So, as the result I get 2 PDF files: one containing all odd pages and the second containing all even pages. I need to merge them the natural way:

1. <- 1.1. (odd.pdf page 1 to result.pdf page 1)
2. <- 2.1. (even.pdf page 1 to result.pdf page 2)
3. <- 1.2. (odd.pdf page 2 to result.pdf page 3)
4. <- 2.2. (even.pdf page 2 to result.pdf page 4)

etc.

share|improve this question
    
Just find a PDF parser and do a merge sort like stuff. –  warl0ck Oct 30 '12 at 10:00
2  
Thanks, captain Obvious! :-] –  Ivan Oct 30 '12 at 10:02
1  
If Stephane doesn't solve your problem, you can try the perl module CAM::PDF, I'll give your a script later. Does the two pdf have same page count? –  warl0ck Oct 30 '12 at 11:24

4 Answers 4

up vote 3 down vote accepted

See the pdfseparate and pdfunite commands from poppler-utils. The first to separate the pages from each document into individual files, and the second to merge them in the order you want in a new document.

Also note that since scanners give you raster images anyway (which some like yours can concatenate into a PDF files), maybe you can configure it to output images (png, tiff...) instead, and do the concatenation into a PDF yourself with ImageMagick.

share|improve this answer
    
This sounds like what I need, let's try... –  Ivan Oct 30 '12 at 10:07
    
Indeed. Excellent. Simple to use to do right what I need. by the way, I have, of course, googled before asking and solutions I've found to exactly the same were notably more complex. –  Ivan Oct 30 '12 at 13:07

Just a bash quick shot using pdfjam:

Build an array of input arguments:

for k in $(seq 1 ${N_PAGES}); do
    PAGES+=(odd.pdf);
    PAGES+=($k);
    PAGES+=(even.pdf);
    PAGES+=($k);
done

This should allow you to use it as input list for pdfjoin:

 pdfjoin ${PAGES[@]} --outfile shuffled.pdf
share|improve this answer
2  
It should be noted that pdfjoin is a wrapper script around pdfjam which is itself a wrapper script around the pdfpages LaTeX package (and pdflatex) so it means that it brings LaTeX as a dependency. –  Stéphane Chazelas Oct 30 '12 at 14:11

pdftk has a shuffle command which collates pages:

pdftk A=even.pdf B=odd.pdf shuffle A B output collated.pdf
share|improve this answer

I was looking to do basically the same thing, and Stéphane Chazelas's answer was very helpful. I do this often enough that I wrote a simple Python script to automate things, using the commands he suggested. By default, it reverses the order of the even pages, but this can be suppressed with a command line flag.

The question is kind of old, so I expect the needs of the original asker have already been met. However, it is possible that the script will be useful to people who arrive here in the future, so I have placed it below.

#!/usr/bin/python
"""A simple script to merge two PDFs."""

import argparse
from os import listdir
from os.path import join as opjoin
import shutil
from subprocess import check_call, CalledProcessError
import tempfile

SEPARATE = 'pdfseparate %s %s'
MERGE = 'pdfunite %s %s'

def my_exec(command):
    """Execute a command from a shell, ignoring errors."""
    try:
        check_call(command, shell=True)
    except CalledProcessError:
        pass

def run(odd, even, out, reverse_odd=False, reverse_even=True):
    """Interleave odd and even pages from two PDF files."""
    folder = tempfile.mkdtemp()
    my_exec(SEPARATE % (odd, opjoin(folder, 'odd%d.pdf')))
    my_exec(SEPARATE % (even, opjoin(folder, 'even%d.pdf')))
    odd_files = []
    even_files = []
    for curr_file in listdir(folder):
        filepath = opjoin(folder, curr_file)
        if curr_file.startswith('odd'):
            odd_files.append((filepath, int(curr_file[3:-4])))
        elif curr_file.startswith('even'):
            even_files.append((filepath, int(curr_file[4:-4])))
    func = lambda x: x[1]
    odd_files.sort(key=func, reverse=reverse_odd)
    even_files.sort(key=func, reverse=reverse_even)
    parts = []
    for line in zip(odd_files, even_files):
        parts.append(line[0][0])
        parts.append(line[1][0])
    my_exec(MERGE % (' '.join(parts), out))
    shutil.rmtree(folder)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Merge two PDF files.')
    parser.add_argument('odd_pages', help='PDF containing the odd pages.')
    parser.add_argument('even_pages', help='PDF containing the even pages.')
    parser.add_argument('output_file', help='The target output file.')
    parser.add_argument('--reverse-odd', action='store_true', 
                        help='Insert the odd pages in reverse order.')
    parser.add_argument('--no-reverse-even', action='store_true',
                        help='Suppress reversal of the even pages.')
    args = parser.parse_args()
    run(args.odd_pages, args.even_pages, args.output_file,
        args.reverse_odd, not args.no_reverse_even)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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