Ada alat baris perintah yang ditulis dalam Java bernama Sejda di mana Anda dapat menemukan splitbybookmarks
perintah yang melakukan persis seperti yang Anda minta. Ini Java sehingga berjalan di Linux dan sebagai alat baris perintah Anda dapat menulis skrip untuk melakukannya.
Penafian
Saya salah satu penulis
Anda memiliki program yang dibuat seperti pdf-split yang dapat melakukannya untuk Anda:
A-PDF Split adalah program utilitas desktop secepat kilat yang sangat sederhana yang memungkinkan Anda membagi file pdf Acrobat apa pun menjadi file pdf yang lebih kecil. Ini memberikan fleksibilitas penuh dan kontrol pengguna dalam hal bagaimana file dipecah dan bagaimana file keluaran terpisah diberi nama secara unik. A-PDF Split menyediakan banyak alternatif untuk membagi file besar Anda - berdasarkan halaman, bookmark, dan halaman ganjil/genap. Bahkan Anda dapat mengekstrak atau menghapus sebagian file PDF. A-PDF Split juga menawarkan pemisahan lanjutan yang dapat disimpan dan kemudian diimpor untuk digunakan dengan tugas pemisahan file berulang. A-PDF Split mewakili fleksibilitas pemisahan file terbaik untuk memenuhi setiap kebutuhan.
A-PDF Split berfungsi dengan file pdf yang dilindungi kata sandi, dan dapat menerapkan berbagai fitur keamanan pdf ke file output yang terpisah. Jika perlu, Anda dapat menggabungkan kembali file terpisah yang dihasilkan dengan file pdf lain menggunakan utilitas seperti Penggabungan A-PDF untuk membentuk file pdf komposit baru.
A-PDF Split TIDAK memerlukan Adobe Acrobat, dan menghasilkan dokumen yang kompatibel dengan Adobe Acrobat Reader Versi 5 dan yang lebih baru.
sunting*
juga menemukan program bersumber terbuka gratis di sini jika Anda tidak ingin membayar.
Ini sedikit program Perl yang saya gunakan untuk tugas itu. Perl tidak istimewa; itu hanya pembungkus di sekitar pdftk untuk menginterpretasikan dump_data
-nya keluaran untuk mengubahnya menjadi nomor halaman untuk diekstrak:
#!perl
use v5.24;
use warnings;
use Data::Dumper;
use File::Path qw(make_path);
use File::Spec::Functions qw(catfile);
my $pdftk = '/usr/local/bin/pdftk';
my $file = $ARGV[0];
my $split_dir = $ENV{PDF_SPLIT_DIR} // 'pdf_splits';
die "Can't find $ARGV[0]\n" unless -e $file;
# Read the data that pdftk spits out.
open my $pdftk_fh, '-|', $pdftk, $file, 'dump_data';
my @chapters;
while( <$pdftk_fh> ) {
state $chapter = 0;
next unless /\ABookmark/;
if( /\ABookmarkBegin/ ) {
my( $title ) = <$pdftk_fh> =~ /\ABookmarkTitle:\s+(.+)/;
my( $level ) = <$pdftk_fh> =~ /\ABookmarkLevel:\s+(.+)/;
my( $page_number ) = <$pdftk_fh> =~ /\BookmarkPageNumber:\s+(.+)/;
# I only want to split on chapters, so I skip higher
# level numbers (higher means more nesting, 1 is lowest).
next unless $level == 1;
# If you have front matter (preface, etc) then this numbering
# will be off. Chapter 1 might be called Chapter 3.
push @chapters, {
title => $title,
start_page => $page_number,
chapter => $chapter++,
};
}
}
# The end page for one chapter is one before the start page for
# the next chapter. There might be some blank pages at the end
# of the split for PDFs where the next chapter needs to start on
# an odd page.
foreach my $i ( 0 .. $#chapters - 1 ) {
my $last_page = $chapters[$i+1]->{start_page} - 1;
$chapters[$i]->{last_page} = $last_page;
}
$chapters[$#chapters]->{last_page} = 'end';
make_path $split_dir;
foreach my $chapter ( @chapters ) {
my( $start, $end ) = $chapter->@{qw(start_page last_page)};
# slugify the title so use it as a filename
my $title = lc( $chapter->{title} =~ s/[^a-z]+/-/gri );
my $path = catfile( $split_dir, "$title.pdf" );
say "Outputting $path";
# Use pdftk to extract that part of the PDF
system $pdftk, $file, 'cat', "$start-$end", 'output', $path;
}
pdftk dapat digunakan untuk membagi file PDF dan mengekstrak nomor halaman bookmark.
Untuk mendapatkan nomor halaman bookmark, lakukan
pdftk in.pdf dump_data
dan buat skrip Anda membaca nomor halaman dari keluaran.
Lalu gunakan
pdftk in.pdf cat A-B output out_A-B.pdf
untuk memasukkan halaman dari A ke B ke out_A-B.pdf.
Skripnya bisa seperti ini:
#!/bin/bash
infile=$1 # input pdf
outputprefix=$2
[ -e "$infile" -a -n "$outputprefix" ] || exit 1 # Invalid args
pagenumbers=( $(pdftk "$infile" dump_data | \
grep '^BookmarkPageNumber: ' | cut -f2 -d' ' | uniq)
end )
for ((i=0; i < ${#pagenumbers[@]} - 1; ++i)); do
a=${pagenumbers[i]} # start page number
b=${pagenumbers[i+1]} # end page number
[ "$b" = "end" ] || b=$[b-1]
pdftk "$infile" cat $a-$b output "${outputprefix}"_$a-$b.pdf
done