---
title: "Extract Text From PDF on Linux Command Line (pdftotext)"
description: "Extract text from PDF files on Linux command line using pdftotext. Covers install, layout modes, password-protected PDFs, OCR for scanned docs & batch scripts."
date: 2026-07-19
categories: ["linux"]
tags: ["pdf","command-line"]
---

import Button from "@components/widgets/Button.astro";
import Notice from "@components/widgets/Notice.astro";
import ListCheck from "@components/widgets/ListCheck.astro";
import Accordion from "@components/widgets/Accordion.astro";
import Tabs from "@components/widgets/Tabs.astro";
import Tab from "@components/widgets/Tab.astro";

Extracting text from PDF files on the Linux command line is straightforward with `pdftotext`, part of the `poppler-utils` package. It converts PDF documents to plain text. No GUI, no cloud services, no accounts. Install the package, point it at a file, and get text out the other side.

This guide covers install, basic usage, every useful option, handling password-protected and scanned PDFs, alternatives when pdftotext is not enough, batch scripts, and troubleshooting.

<ListCheck>
<ul>
<li>Install poppler-utils on any major Linux distro</li>
<li>Extract text from PDFs with pdftotext (basic and advanced)</li>
<li>Handle password-protected and scanned/image-based PDFs</li>
<li>Use batch scripts to process multiple PDFs at once</li>
<li>Troubleshoot common extraction failures</li>
</ul>
</ListCheck>

## What is poppler-utils?

Poppler-utils is a collection of command-line utilities for manipulating PDF files. It is based on the [poppler library](https://poppler.freedesktop.org/), a fork of the xpdf library. The star of this package is `pdftotext`, which converts PDF files to plain text with configurable layout, encoding, and page selection.

Other tools in the package handle different PDF tasks:

### Key poppler-utils tools at a glance

| Tool | Purpose |
|------|---------|
| **pdftotext** | Convert PDF to plain text (the focus of this article) |
| **pdfinfo** | Print PDF metadata: title, author, page count, etc. |
| **pdftohtml** | Convert PDF to HTML |
| **pdfimages** | Extract images from a PDF |
| **pdfseparate** | Split a PDF into single-page files |
| **pdfunite** | [Merge PDF files with pdfunite](https://www.bitdoze.com/pdf-merge-linux-cmd/) into one |

If you work with PDFs from the terminal regularly, poppler-utils is one of those packages you install once on every server. It pairs well with other [essential Linux commands](https://www.bitdoze.com/linux-commands/) you use daily.

## How to install poppler-utils on Linux

Poppler-utils is in the official repositories of every major Linux distribution. Pick your distro below.

<Tabs>
<Tab name="Ubuntu / Debian / Mint">
```sh
sudo apt install poppler-utils
```
</Tab>
<Tab name="Fedora / RHEL 8+ / CentOS Stream">
```sh
sudo dnf install poppler-utils
```
</Tab>
<Tab name="Arch Linux / Manjaro">
```sh
sudo pacman -S poppler
```
</Tab>
<Tab name="Alpine Linux">
```sh
sudo apk add poppler-utils
```
</Tab>
<Tab name="openSUSE">
```sh
sudo zypper install poppler-tools
```
</Tab>
</Tabs>

<Notice type="info" title="Legacy RHEL/CentOS 7">
If you are still on RHEL/CentOS 7, use `sudo yum install poppler-utils`. On anything newer (RHEL 8+, Fedora, AlmaLinux, Rocky Linux), use `dnf`.
</Notice>

### Verify installation

Run:

```sh
pdftotext --version
```

Expected output (version will vary by distro):

```
pdftotext version 24.02.0
Copyright 2005-2024 The Poppler Developers - http://poppler.freedesktop.org
Copyright 1996-2011 Glyph & Cog, LLC
```

If you get `command not found`, the package is not installed or not in your PATH. Re-run the install command for your distro.

<Notice type="info" title="Check your version for newer features">
Some options require minimum poppler versions:
- **`-tsv`** needs poppler ≥ 22.05.0 (Ubuntu 22.10+, Fedora 37+, Arch rolling)
- **`-remove-hyphens`** needs poppler >= 26.05.0 (May 2026). Only on rolling distros or manual builds, NOT in Ubuntu 24.04 (ships 24.02.0).

Check with `pdftotext --version` before relying on these features.
</Notice>

## How to use pdftotext: basic text extraction

### Basic syntax and first extraction

The simplest invocation takes an input PDF and produces a text file:

```sh
pdftotext input.pdf output.txt
```

If you omit the output filename, pdftotext uses the same name with a `.txt` extension:

```sh
pdftotext input.pdf
# Creates input.txt in the current directory
```

Verify it worked:

```sh
wc -l output.txt
```

If the line count is zero or near-zero, the PDF is likely scanned/image-based. See the OCR section below.

### Reading from stdin and writing to stdout

You can pipe PDF data in and text out using `-` as the filename:

```sh
cat input.pdf | pdftotext - -
```

This is useful in scripts and pipelines where you do not want intermediate files:

```sh
pdftotext report.pdf - | grep -i "quarterly revenue"
```

## Customize output format with pdftotext options

pdftotext has many options for controlling how text comes out. They fall into a few groups.

<Accordion label="Layout control: -layout, -raw, -fixed" group="options" expanded="true">

- **`-layout`**: Preserves the original layout of the PDF, including columns, tables, and spacing. This is my default for multi-column documents.

  ```sh
  pdftotext -layout input.pdf output.txt
  ```

- **`-raw`**: Keeps the original text order but ignores layout positioning. Useful when `-layout` garbles text due to unusual fonts.

  ```sh
  pdftotext -raw input.pdf output.txt
  ```

- **`-fixed number`**: Assumes fixed-pitch (monospace) text with the given character width in points. Useful for PDFs that were generated from fixed-width text.

  ```sh
  pdftotext -fixed 8 input.pdf output.txt
  ```

- **`-colspacing number`**: Controls column detection threshold (default: 0.7). Lower values (e.g., 0.3) detect narrower column gaps; higher values (e.g., 1.5) are more lenient. Adjust when columns are getting merged or split incorrectly.

  ```sh
  pdftotext -layout -colspacing 0.3 input.pdf output.txt
  ```

</Accordion>

<Accordion label="Page selection: -f and -l" group="options">

Extract a specific page range:

```sh
# Extract only pages 5 through 12
pdftotext -f 5 -l 12 input.pdf output.txt
```

- **`-f number`**: First page to extract (1-based).
- **`-l number`**: Last page to extract.

Combine with other options:

```sh
pdftotext -f 1 -l 5 -upw "mypass" -layout report.pdf pages1-5.txt
```

</Accordion>

<Accordion label="Structured output: -bbox, -tsv, -htmlmeta" group="options">

These options generate structured output for programmatic processing:

- **`-bbox`**: Generates HTML with bounding box coordinates for each word. Useful for positional text analysis.

  ```sh
  pdftotext -bbox input.pdf output.html
  ```

- **`-tsv`**: Outputs tab-separated values with bounding box data per block, line, and word. Columns: `level`, `page_num`, `par_num`, `block_num`, `line_num`, `word_num`, `left`, `top`, `width`, `height`, `conf`, `text`.

  ```sh
  pdftotext -tsv input.pdf output.tsv
  ```

  <Notice type="info" title="TSV mode requires poppler ≥ 22.05.0">
  Available in Ubuntu 22.10+, Fedora 37+, Arch rolling. Check your version with `pdftotext --version`.
  </Notice>

- **`-htmlmeta`**: Generates HTML with PDF metadata (title, author) embedded.

  ```sh
  pdftotext -htmlmeta input.pdf output.html
  ```

- **`-bbox-layout`**: Like `-bbox` but preserves layout structure in the HTML output.

</Accordion>

<Accordion label="Text cleanup: -nodiag, -remove-hyphens, -eol" group="options">

- **`-nodiag`**: Discards diagonal text. This is useful for removing watermark text that appears at an angle in the PDF.

  ```sh
  pdftotext -nodiag input.pdf output.txt
  ```

- **`-remove-hyphens all|soft|none`**: Controls how end-of-line hyphens are handled:
  - `all`: Remove all end-of-line hyphens and merge words (default)
  - `soft`: Only remove soft hyphens (U+00AD), keep ASCII hyphens
  - `none`: Keep all hyphens and line breaks

  ```sh
  pdftotext -remove-hyphens all input.pdf output.txt
  pdftotext -remove-hyphens soft input.pdf output.txt
  ```

  <Notice type="warning" title="-remove-hyphens requires poppler ≥ 26.05.0">
  This option was added in May 2026. It is NOT in Ubuntu 24.04 (ships 24.02.0). Only available on rolling distros (Arch) or via manual compile. Has no effect in `-raw` or `-layout` mode.
  </Notice>

- **`-eol unix|dos|mac`**: Sets the end-of-line convention in the output text. Default is the host OS convention.

  ```sh
  pdftotext -eol dos input.pdf output.txt
  ```

</Accordion>

<Accordion label="Output encoding and other options: -enc, -nopgbrk, -q, -r" group="options">

- **`-enc encoding`**: Sets the output text encoding. Common values: `UTF-8`, `ISO-8859-1`, `ASCII`, `UCS-2`.

  ```sh
  pdftotext -enc UTF-8 input.pdf output.txt
  ```

- **`-nopgbrk`**: Removes form feed characters (`^L`) between pages. Default behavior inserts them.

- **`-q`**: Quiet mode. Suppresses error messages.

- **`-r number`**: Sets the resolution in DPI (default: 72). Affects output of some rendering-dependent options.

- **`-x number -y number -W number -H number`**: Crop area coordinates. Defines a rectangular region to extract text from.

  ```sh
  pdftotext -x 100 -y 100 -W 400 -H 600 input.pdf output.txt
  ```

- **`-cropbox`**: Uses the crop box instead of the media box (with `-bbox`).

</Accordion>

You can see the full list of options with:

```sh
pdftotext -h
```

## Extract text from password-protected PDFs

Many PDFs have restrictions that prevent copying or printing text. pdftotext can handle two types of passwords.

### Using -opw and -upw options

- **`-opw "password"`** — Owner password. Bypasses all restrictions (printing, copying, modifying). Use this when the PDF lets you open it but blocks text extraction.

  ```sh
  pdftotext -opw "ownerpass" restricted.pdf output.txt
  ```

- **`-upw "password"`** — User password. Required to open the file at all. Use this when the PDF prompts for a password on open.

  ```sh
  pdftotext -upw "userpass" locked.pdf output.txt
  ```

If you get exit code 3 or "Permission denied" errors, the PDF has restrictions. Try `-opw` first.

### Decrypting with qpdf before extraction

For complex encryption or when pdftotext's password options do not work, decrypt the PDF first with `qpdf`:

```sh
# Install qpdf
sudo apt install qpdf

# Decrypt
qpdf --password=secret --decrypt locked.pdf unlocked.pdf

# Then extract
pdftotext unlocked.pdf output.txt
```

This removes all password protection permanently from `unlocked.pdf`, so handle it accordingly.

## When pdftotext doesn't work: OCR for scanned PDFs

<Notice type="warning" title="pdftotext cannot read scanned PDFs">
If your PDF was created by scanning paper documents, it contains images, not text. `pdftotext` will produce empty or near-empty output. You need OCR (optical character recognition) to add a text layer.
</Notice>

This is the number one reason pdftotext "doesn't work" for people. A scanned PDF looks like it has text on screen, but the text is actually a picture of text.

### How to detect a scanned/image-based PDF

Quick check:

```sh
pdftotext suspect.pdf - | wc -c
```

If the byte count is very low (under 100 bytes for a multi-page document), the PDF is almost certainly scanned. You can also use `pdfinfo`:

```sh
pdfinfo suspect.pdf | grep Pages
```

If it shows many pages but pdftotext extracts almost nothing, it is scanned.

### Solution 1: OCRmyPDF + Tesseract

OCRmyPDF adds an invisible OCR text layer to scanned PDFs, making them searchable and extractable:

```sh
# Install
sudo apt install ocrmypdf tesseract-ocr

# Add OCR text layer
ocrmypdf scanned.pdf searchable.pdf

# Now extract text
pdftotext searchable.pdf output.txt
```

Verify it worked:

```sh
pdftotext searchable.pdf - | wc -c
# Should show substantial byte count
```

For non-English PDFs, install the appropriate Tesseract language pack:

```sh
# French
sudo apt install tesseract-ocr-fra

# German
sudo apt install tesseract-ocr-deu

# Then specify language
ocrmypdf -l fra scanned.pdf searchable.pdf
```

### Solution 2: pdftoppm + tesseract directly

If OCRmyPDF is not available or you need more control over the OCR process, convert PDF pages to images first, then run Tesseract:

```sh
# Convert PDF pages to PPM images at 300 DPI
pdftoppm -r 300 scanned.pdf page

# OCR the first page
tesseract page-1.ppm output

# Output will be in output.txt
```

This approach gives you control over resolution and per-page processing, but you need to loop over multiple pages yourself.

## Alternative command-line tools for PDF text extraction

pdftotext handles most cases, but sometimes you need a different tool. Here is when to reach for something else.

| Tool | When to use it | Install |
|------|---------------|---------|
| **mutool draw** | Complex layouts where pdftotext garbles columns | `sudo apt install mupdf-tools` |
| **pdfgrep** | Search PDFs without extracting everything | `sudo apt install pdfgrep` |
| **xpdf pdftotext** | Tabular data (has `-table` mode poppler lacks) | `sudo apt install xpdf` |
| **calibre ebook-convert** | Ebook workflows, different extraction engine | `sudo apt install calibre` |

If you prefer a web-based GUI for PDF operations, take a look at [self-hosted PDF manipulation with Stirling PDF](https://www.bitdoze.com/stirling-pdf-self-host-manipulation/) — it runs in Docker and handles extraction, conversion, merging, and more through a browser.

### mutool draw (MuPDF)

Sometimes handles complex layouts better than pdftotext:

```sh
mutool draw -F txt input.pdf -o output.txt
```

### pdfgrep — search PDFs without full extraction

When you just need to find a string in a PDF, not extract the whole thing:

```sh
pdfgrep -n "search term" document.pdf

# Search across multiple PDFs
pdfgrep -rn "search term" *.pdf
```

### xpdf pdftotext (with -table mode)

xpdf's version of pdftotext has options that poppler's does not, notably `-table` for tabular data and `-simple` for single-column layouts:

```sh
sudo apt install xpdf
pdftotext -table input.pdf output.txt
```

<Notice type="info" title="xpdf vs poppler pdftotext">
These are two different binaries with the same name. On Ubuntu, installing xpdf may change which `pdftotext` is in your PATH. Check with `which pdftotext` and `pdftotext --version` to confirm which one you are running. xpdf's version shows "xpdf version" in its output; poppler's shows "poppler" copyright.
</Notice>

### calibre ebook-convert

A heavier tool, but useful for ebook-oriented workflows:

```sh
ebook-convert input.pdf output.txt
```

## Batch processing and practical scripts

### Extract all PDFs in a directory

```sh
for pdf in *.pdf; do
    pdftotext -layout "$pdf" "${pdf%.pdf}.txt"
done
```

This creates a `.txt` file for every `.pdf` in the current directory.

### Pipe extracted text to grep for searching

Search within a PDF without creating intermediate files:

```sh
pdftotext document.pdf - | grep -i "keyword"
```

After extracting text, you can [transform text case with sed](https://www.bitdoze.com/sed-change-case/) or do further text processing in your pipeline.

### One-liner to verify extraction succeeded

Use this in scripts to check if extraction produced real output:

```sh
test $(wc -c < output.txt) -gt 10 && echo "OK" || echo "LIKELY SCANNED PDF"
```

Combine with password and page range:

```sh
pdftotext -f 1 -l 5 -upw "mypass" -layout report.pdf pages1-5.txt
test $(wc -c < pages1-5.txt) -gt 10 && echo "Extraction OK" || echo "Failed or empty"
```

When batch processing, you may also find it useful to [compare folder contents](https://www.bitdoze.com/compare-folders-content-differences/) to verify all expected output files were created.

## Troubleshooting common pdftotext issues

<Accordion label="Empty output (scanned PDF)" group="troubleshooting" expanded="true">

**Symptom:** `pdftotext` produces an empty or near-empty output file.

**Cause:** The PDF is scanned/image-based with no text layer.

**Fix:** Use OCRmyPDF to add an OCR text layer (see the [OCR section](#when-pdftotext-doesnt-work-ocr-for-scanned-pdfs) above).

</Accordion>

<Accordion label="Garbled or missing text" group="troubleshooting">

**Symptom:** Extracted text has wrong characters, missing letters, or garbled output.

**Cause:** The PDF uses custom font encodings that pdftotext cannot map to Unicode.

**Fixes:**
1. Try `-raw` mode to bypass layout processing:
   ```sh
   pdftotext -raw input.pdf output.txt
   ```
2. Force UTF-8 encoding:
   ```sh
   pdftotext -enc UTF-8 input.pdf output.txt
   ```
3. If poppler cannot handle it, try `mutool draw -F txt` as an alternative.

</Accordion>

<Accordion label="Bad column detection" group="troubleshooting">

**Symptom:** Columns are merged together or text from different columns is interleaved.

**Cause:** The column detection heuristic does not match the PDF's layout.

**Fix:** Adjust `-colspacing` (default: 0.7). Lower values detect narrower column gaps:

```sh
pdftotext -layout -colspacing 0.3 input.pdf output.txt
```

Try values between 0.3 and 1.5 until the layout looks right.

</Accordion>

<Accordion label="Watermark text in output" group="troubleshooting">

**Symptom:** Diagonal watermark text (e.g., "CONFIDENTIAL", "DRAFT") appears in the extracted text.

**Cause:** pdftotext extracts all text, including diagonal overlays.

**Fix:** Use `-nodiag` to discard diagonal text (poppler ≥ 0.80.0):

```sh
pdftotext -nodiag input.pdf output.txt
```

</Accordion>

<Accordion label="Understanding pdftotext exit codes" group="troubleshooting">

For scripting and automation, pdftotext returns meaningful exit codes:

| Exit code | Meaning |
|-----------|---------|
| 0 | Success |
| 1 | Error opening PDF file |
| 2 | Error opening output file |
| 3 | Permission error (PDF has restrictions) |
| 99 | Other error |

Use in scripts:

```sh
pdftotext input.pdf output.txt
case $? in
    0) echo "Success" ;;
    1) echo "Cannot open PDF" ;;
    3) echo "PDF has restrictions — try -opw option" ;;
    *) echo "Unknown error" ;;
esac
```

</Accordion>

## Conclusion

`pdftotext` from `poppler-utils` is the default tool for extracting text from PDFs on Linux. It handles most cases out of the box: basic conversion, layout preservation, page selection, encoding control, and password-protected files. For scanned PDFs, pair it with OCRmyPDF and Tesseract. For tabular data that pdftotext mangles, try xpdf's `-table` mode or `mutool draw`.

For more PDF work on the command line, you can [merge PDF files with pdfunite](https://www.bitdoze.com/pdf-merge-linux-cmd/) or [self-host Stirling PDF](https://www.bitdoze.com/stirling-pdf-self-host-manipulation/) for a browser-based toolkit. And if you are building out your Linux admin skills, check out guides on [securing your SSH server](https://www.bitdoze.com/secure-ssh-server-linux/) and [checking remote ports with nc](https://www.bitdoze.com/check-remote-port-in-linux-nc/).