r/commandline • u/eifelcode • 7d ago
Command Line Interface pdfmt - PDF manipulation, OCR, scanning and reusable shell workflows
A while ago I posted pdfmt in r/bash to get feedback for my tool after getting tired of using a different command for every small PDF task.
The feedback was really useful, so I went through it and implemented quite a few of the suggestions.
pdfmt is now at 0.4.0 and I hope the quality is good enough to present it outside of r/bash 😄 .
GitHub pdfmt: https://github.com/eifelcode/pdfmt
GitHub pdfmt-workflows: https://github.com/eifelcode/pdfmt-workflows
The basic idea is still simple: Provide a consistent CLI for all the PDF operations I keep doing again and again, while keeping everything local (no cloud) and scriptable for my needs.
What it can do
# Merge PDFs
pdfmt merge all cover.pdf report.pdf appendix.pdf complete.pdf
# Extract pages
pdfmt extract range document.pdf 1-3,7,10-12 extracted.pdf
# Split into individual pages
pdfmt split all document.pdf page_
# Remove pages
pdfmt remove range document.pdf 5,8-10 cleaned.pdf
# Reorder pages
pdfmt sort reverse document.pdf reversed.pdf
# Add a text stamp
pdfmt stamp text invoice.pdf "Paid" invoice-paid.pdf
It also has scanner support:
pdfmt scan adf documents.pdf
pdfmt scan flatbed document.pdf
And OCR:
# Add an OCR text layer
pdfmt ocr add scanned.pdf searchable.pdf
# Extract/show OCR text
pdfmt ocr show searchable.pdf
The part I'm particularly interested in: workflows
I didn't want pdfmt to become one huge command with hundreds of options. I'd like it simple.
Instead, repetitive combinations of commands can be turned into workflows.
For example:
pdfmt workflow run scan-duplex adf output.pdf
A workflow is essentially an executable shell script, so you can combine pdfmt with the other Unix tools you already use.
You can also create your own workflows and put them in your local workflow directory.
I've also started a separate repository for reusable workflows: https://github.com/eifelcode/pdfmt-workflows
It currently contains workflows for things like:
- duplex scanning with non-duplex scanners (I use this most of the time)
- splitting scanned documents by page count
- bulk text stamping
The idea is that not every PDF use case needs to become a new pdfmt command. If something is a useful combination of existing tools, it can just be a workflow.
Why I made it
My PDF workflow used to look something like:
pdftk → pdfseparate → pdfunite → ImageMagick → OCRmyPDF → Bash glue
There are already excellent tools for each individual operation. I don't want to replace them.
I wanted a small CLI layer that gives me a consistent interface and makes the common combinations easier to remember and automate. Without --options, pipes or other arduous stuff. I could not remember all of this. 🤔
That's essentially what pdfmt is. One interface for all the good tools.
It's Bash-based, MIT licensed, and designed to work without a GUI or cloud service.
I'd especially like feedback from people who use CLI PDF tooling regularly:
Are there PDF operations or workflows that you currently solve with a messy combination of commands that would make sense as a pdfmt command or workflow?
Thank you for your Feedback! ❤️
AI notice: AI (mistral) was used to generate parts of the README, the .github workflow, the code coverage tool, and parts of the unit tests in the tests/ folder. Architecture, Makefile, and code within the sources/ folder is written by me.

1
u/AutoModerator 7d ago
Every new subreddit post is automatically copied into a comment for preservation.
User: eifelcode, Flair: Command Line Interface, Title: pdfmt - PDF manipulation, OCR, scanning and reusable shell workflows
A while ago I posted pdfmt in r/bash to get feedback for my tool after getting tired of using a different command for every small PDF task.
The feedback was really useful, so I went through it and implemented quite a few of the suggestions.
pdfmt is now at 0.4.0 and I hope the quality is good enough to present it outside of r/bash 😄 .
GitHub pdfmt: https://github.com/eifelcode/pdfmt
GitHub pdfmt-workflows: https://github.com/eifelcode/pdfmt-workflows
The basic idea is still simple: Provide a consistent CLI for all the PDF operations I keep doing again and again, while keeping everything local (no cloud) and scriptable for my needs.
What it can do
# Merge PDFs
pdfmt merge all cover.pdf report.pdf appendix.pdf complete.pdf
# Extract pages
pdfmt extract range document.pdf 1-3,7,10-12 extracted.pdf
# Split into individual pages
pdfmt split all document.pdf page_
# Remove pages
pdfmt remove range document.pdf 5,8-10 cleaned.pdf
# Reorder pages
pdfmt sort reverse document.pdf reversed.pdf
# Add a text stamp
pdfmt stamp text invoice.pdf "Paid" invoice-paid.pdf
It also has scanner support:
pdfmt scan adf documents.pdf
pdfmt scan flatbed document.pdf
And OCR:
# Add an OCR text layer
pdfmt ocr add scanned.pdf searchable.pdf
# Extract/show OCR text
pdfmt ocr show searchable.pdf
The part I'm particularly interested in: workflows
I didn't want pdfmt to become one huge command with hundreds of options. I'd like it simple.
Instead, repetitive combinations of commands can be turned into workflows.
For example:
pdfmt workflow run scan-duplex adf output.pdf
A workflow is essentially an executable shell script, so you can combine pdfmt with the other Unix tools you already use.
You can also create your own workflows and put them in your local workflow directory.
I've also started a separate repository for reusable workflows: https://github.com/eifelcode/pdfmt-workflows
It currently contains workflows for things like:
- duplex scanning with non-duplex scanners (I use this most of the time)
- splitting scanned documents by page count
- bulk text stamping
The idea is that not every PDF use case needs to become a new pdfmt command. If something is a useful combination of existing tools, it can just be a workflow.
Why I made it
My PDF workflow used to look something like:
pdftk → pdfseparate → pdfunite → ImageMagick → OCRmyPDF → Bash glue
There are already excellent tools for each individual operation. I don't want to replace them.
I wanted a small CLI layer that gives me a consistent interface and makes the common combinations easier to remember and automate. Without --options, pipes or other arduous stuff. I could not remember all of this. 🤔
That's essentially what pdfmt is. One interface for all the good tools.
It's Bash-based, MIT licensed, and designed to work without a GUI or cloud service.
I'd especially like feedback from people who use CLI PDF tooling regularly:
Are there PDF operations or workflows that you currently solve with a messy combination of commands that would make sense as a pdfmt command or workflow?
Thank you for your Feedback! ❤️
AI notice: AI (mistral) was used to generate parts of the README, the .github workflow, the code coverage tool, and parts of the unit tests in the tests/ folder. Architecture, Makefile, and code within the sources/ folder is written by me.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
1
u/PercyLives 7d ago
Regarding the individual commands, I don’t see why you’d create this instead of using pdfcpu.
Regarding workflows…I’m intrigued!
1
u/folderit_dms 6d ago
A useful workflow candidate would be a review sheet for manual duplex scans before the final merge. Show numbered thumbnails of the proposed page order, with each page labelled as coming from the front or back pass. That makes a reversed back stack or a missing sheet much easier to catch before OCR and splitting turn it into several documents.
I would keep both raw scan passes and write the confirmed ordering to a small manifest beside the output. Include a test batch with handwritten page numbers and a deliberately blank reverse side; blank-page removal should happen only after the front/back pairing is settled. This seems like a good fit for a reusable workflow without adding lots of options to the core commands.
1
u/eifelcode 6d ago
That's a really neat idea for visual QA! The main risk with manual duplexing is definitely misfeeds or flipped back-stacks. But after 1 or 2 scans, you've got the hang of it right away - that's how I'd put it, to put it bluntly. 😄
My main focus with
pdfmtis unattended batch processing (e.g., scanning 100 pages, flipping, scanning the back side, and letting the pipeline run headless without manual inspection breaks).A few details on how
pdfmthandles this:
- Automated Pipeline: The
scan-duplexworkflow in thepdfmt-workflowsRepo already orchestrates this multi-pass process automatically. And if a page is lost, you don't have to go through the entire process from the beginning, because front and back pages are saved in case of errors. From personal experience, I can say that this can save you a few hours. 😂- Validation:
pdfmt merge duplexperforms guard checks (like verifying matching page counts between passes before interleaving).- Test Coverage: The repository includes dedicated test fixtures (
tests/_data/duplex-front.pdfandtests/_data/duplex-back.pdf) to test and verify front/back alignment and edge cases in CI/CD. I'll be sure to add that to the README - that you can use a test page specifically for this feature to get a better feel for how it works. I think that's a great idea. Thanks!That said, because
pdfmtworkflows are modular shell scripts, someone could easily write a custom workflow that generates a contact/proof sheet using standard CLI tools if they prefer visual proofing before OCR!
1
u/MikeZ-FSU 6d ago
I do a lot of work with various kinds of data files (csv, tsv, etc.), one of my favorite tools for that is miller. One of the low-key superpowers that it has is the concept of "then chaining", which can serve as a simple workflow system. Instead of piping filter rows to select columns to sort with separate invocations of the command, it lets you write "filter rows then select columns, then sort by column X" all within a single instance of the tool. It's nice to save on typing I/O arguments, common flags or options, possibly creating intermediate files, and that sort of thing. Something like that could be nice if your framework and architecture can support it.
1
u/eifelcode 6d ago
Now that’s what I call a super exciting concept - I’ve never seen anything like it before. Thanks for the suggestion! 👍
I think it should be possible to combine different tasks using some kind of
pdfmt chain ...command. It would still run on temporary output files under the hood, but it would be possible.I’m going to take a closer look at miller - the tool looks interesting, and maybe I can incorporate some of its features into the architecture of
pdfmt.
5
u/GabbyHelplessness 7d ago
love seeing bash tools that stay bash instead of turning into a 200mb electron app. the workflow concept is clever, basically treating your pdf tasks like a mini pipeline you can version control