Ghostscript script or other, to interleave odd and even pages from two multipage pdf files
-
29-06-2021 - |
Question
My scanner has a paper feed but no duplex scanning. Thus, if I scan a multi-page document that is printed on both sides of the sheet, I will end up with two pdf files, one containing all odd pages (the odd-page pdf file), the other all even pages (the even-page pdf file).
I feel it should be possible to have a Ghostscript script that merges the two files in such a way that each page from the even-page pdf file will be added as every other page to the odd-page pdf file.
Would anyone know how to do that?
Preferably, the script would take arguments, so that the first argument specifies the output file, the second argument the odd-page pdf file and the third argument the even-page pdf file.
Solution
So, if I rightly understand, you have two pdf files
- odd.pdf
- even.pdf
and you need to INTERLEAVE these pages from these two multipage pdf files: (odd, even, odd... and so on...)
I wrote some time ago, for same needs, a script I attach, it is INTERACTIVE, meaning it asks for arguments, if you prefer a NON INTERACTIVE SCRIPT, I can modify it
it only needs PDFTK
#!/bin/bash
#script able to interleave the pages of two pdf files, saving the result in a new pdf file. Useful for any use, specially to mount parallel text books
echo "enter the name (with extension) of first PDF"
read filename1
echo "enter the name (with extension) of second PDF"
read filename2
pages1="`pdftk $filename1 dump_data output |grep Pages|cut -f2 -d :`"
pages2="`pdftk $filename2 dump_data output |grep Pages|cut -f2 -d :`"
if [ $pages1 -gt $pages2 ]
then
pagesincr="$(echo "scale=0; $pages2+1" |bc -l)"
echo "$filename1 has $pages1 pages"
echo "$filename2 has $pages2 pages"
rule="$(for x in $(seq 1 $pages2); do echo -n "A$x B$x "; done; for x in $(seq $pagesincr $pages1); do echo -n "A$x ";done)"
echo $rule
elif
[ $pages2 -gt $pages1 ]
then
pagesincr="$(echo "scale=0; $pages1+1" |bc -l)"
echo "$filename1 has $pages1 pages"
echo "$filename2 has $pages2 pages"
rule="$(for x in $(seq 1 $pages1); do echo -n "A$x B$x "; done; for x in $(seq $pagesincr $pages2); do echo -n "B$x ";done)"
echo $rule
else
echo "$filename1 has $pages1 pages"
echo "$filename2 has $pages2 pages"
rule="$(for ((a=1, b=1; a <= $pages1, b <= $pages2 ; a++, b++)); do echo -n "A$a B$b "; done)"
echo $rule
fi
pdftk A=$filename1 B=$filename2 cat $rule output interleaved.pdf
echo "file created!"
exit 0
OTHER TIPS
Much simpler: (from superuser)
pdftk A=even.pdf B=odd.pdf shuffle A B output merged.pdf
or if B has pages in reversed order:
pdftk A=even.pdf B=odd.pdf shuffle A Bend-1 output merged.pdf
I tried Dingo's script above and it seems to work well.
However, in my case the pages in the "even" file are reversed. I just flipped the entire stack of pages over and placed back in the scanner. So if I had 5 double sided pages that I scanned I'd have:
Odd: 1, 3, 5, 7, 9
Even: 10, 8, 6, 4, 2
What I need is the final output to be: A1 B5 A2 B4 A3 B3 A4 B2 A5 B1
#!/bin/bash
#script able to interleave the pages of two pdf files, saving the result in a new pdf file.
#Useful for any use, specially to mount parallel text books
# This version assumes that filename2 is in the reverse order
# This is normally what happens if you just flip the pages over
# and scan the second side.
args=$#
if [[ $args -ge 2 ]]
then
filename1=$1
filename2=$2
if [[ $args -ge 3 ]]
then
outputfile=$3
else
outputfile="interleaved.pdf"
echo "output file will be: $outputfile"
fi
else
echo "enter the name (with extension) of first PDF"
read filename1
echo "enter the name (with extension) of second PDF"
read filename2
echo "enter the name (with extension) of the output PDF"
read outputfile
fi
pages1="`pdftk "$filename1" dump_data output |grep Pages|cut -f2 -d :`"
pages2="`pdftk "$filename2" dump_data output |grep Pages|cut -f2 -d :`"
if [ $pages1 -gt $pages2 ]
then
pagesincr="$(echo "scale=0; $pages2+1" |bc -l)"
echo "$filename1 has $pages1 pages"
echo "$filename2 has $pages2 pages"
rule="$(for ((a=1, b=$pages2 ; a <= $pages1, b >= 1 ; a++, b--)); do echo -n "A$a B$b "; done; for x in $(seq $pagesincr 1 $pages1); do echo -n "A$x ";done)"
echo $rule
elif [ $pages2 -gt $pages1 ]
then
echo "$filename1 has $pages1 pages"
echo "$filename2 has $pages2 pages"
pagesincr=$(($pages2 - $pages1))
echo $pagesincr
rule="$(for ((a=1, b=$pages2 ; a <= $pages1, b >= (($pages2 - $pages1 + 1)) ; a++, b--)); do echo -n "A$a B$b "; done; for x in $(seq $pagesincr -1 1); do echo -n "B$x ";done)"
echo $rule
else
echo "$filename1 has $pages1 pages"
echo "$filename2 has $pages2 pages"
rule="$(for ((a=1, b=$pages2 ; a <= $pages1, b >= 1 ; a++, b--)); do echo -n "A$a B$b "; done)"
echo $rule
fi
pdftk A="$filename1" B="$filename2" cat $rule output "$outputfile"
echo "file created!"
exit 0
NB. You can either supply the file names on the command line or the script will ask you for them.
Hope that helps someone else.
The problem is that you need to have 2 PDF files open at once to do this efficiently, and that isn't currently possible I don't think.
The only way I can think of quickly to do this would be to use the '%d' format OutputFile option to output each page of each PDF to a separate file. You could then feed the individual files back to Ghostscript to combine them all into a single final PDF file.
You probably could do it by writing some PostScript to do essentially the same task, but its probably easier with a shell script.
If you want to merge PDFs interleaving pages, use jPDF Tweak. To reverse order all pages, use PDFTools
I coded a java-application (Windows/Linux) which does exactly that! You have to scan all even pages in one PDF, then all odd pages in a PDF (using the feeder) and after that you can use this tool to combine them:
http://sourceforge.net/projects/duplexmerger/
You just have to put in the path's of the 2 PDF files, the rest will be handled automatically. :)