Home / Alt manpages / pr(1)

  • pr(1)
  • User command
  • linux

Format Text for Printing with GNU pr

GNU pr turns plain text into paginated or columnated output, the kind of thing you reach for once a year and then have to relearn from scratch. This covers page headers, compact output, line numbers, columns and merging files side by side, with every result checked before anything goes near a printer. Allow about ten minutes. You need a shell and GNU coreutils; no elevated privileges unless the input or output directory is deliberately restricted.

1. Check the installed command

This guide follows GNU coreutils pr 9.4. Check your own build before putting an option into a script:

$ command -v pr
/usr/bin/pr
$ pr --version | head -2
pr (GNU coreutils) 9.4
Copyright (C) 2023 Free Software Foundation, Inc.

GNU pr reads named files, or standard input when there is no file or the name is -. It writes formatted text to standard output and never edits the input file.

Checkpoint

If command -v pr finds a different implementation, read that implementation's manual before relying on GNU-specific details such as the long options shown here.

2. See the default paginated form

Create a small input file, or point at an existing text file you want to inspect:

$ printf '%s\n' alpha bravo charlie delta echo foxtrot > input.txt
$ pr input.txt | sed -n '1,8p'


2026-09-26 12:01          input.txt          Page 1


alpha
bravo
charlie

The header spacing and time will differ on your run. By default GNU pr uses a 66-line page including a header and trailer, leaving 56 lines of text. The header carries the date, file name and page number; the first two blank lines in the sample are part of that five-line header structure.

  • Do not trust the date. It is generated when the command runs, not a document timestamp.
  • Quote file names with spaces the normal way: pr '/path/to/meeting notes.txt'.
$ pr '/path/to/meeting notes.txt' > meeting-notes.txt

The redirection creates or truncates meeting-notes.txt before pr even starts. If that destination already holds something useful, do not run this blindly: pick a new name, or write to a temporary file and swap it in only after checking it.

3. Strip headers for clean text

Use -t (--omit-header) when you want the content without page headers or trailers:

$ pr -t input.txt
alpha
bravo
charlie
delta
echo
foxtrot

Handy for a quick column layout, or a pipeline where a print header would just be misleading. It does not remove form-feed characters already present in the input though. For that, add -T as well, which also strips input pagination:

$ pr -T input.txt > unpaginated.txt
$ test -s unpaginated.txt && echo 'output exists'
output exists

The input file itself is untouched; only the new output file changes.

4. Number lines for review

Add -n to prefix each output line with a number, five digits and a tab by default:

$ pr -t -n input.txt
    1	alpha
    2	bravo
    3	charlie
    4	delta
    5	echo
    6	foxtrot

These numbers come from pr itself, not from the source file. To start at something other than 1, use -N:

$ pr -t -N 100 input.txt | sed -n '1,2p'
  100	alpha
  101	bravo

Numbering is purely presentational. If the result is going into another program, check that it actually expects the added prefix rather than treating it as data.

5. Arrange one file in columns

Use -2 for two columns. Without -a, pr fills columns down the page before starting the next one:

$ pr -t -2 input.txt
alpha				    delta
bravo				    echo
charlie				    foxtrot

That large gap is normal: GNU pr reserves space inside the default 72-character width. Add -a when the input should instead run across each row:

$ pr -t -a -2 input.txt
alpha				    bravo
charlie				    delta
echo				    foxtrot

For a different width use -w, but remember it applies to multi-column text output. -W sets the page width unconditionally and can truncate long lines, so keep an eye on that in scripts: truncation loses data silently, without a non-zero exit status to warn you.

6. Merge separate files side by side

Use -m when each input file should occupy its own column. A separator makes the result easier to read:

$ printf '%s\n' A1 A2 A3 > left.txt
$ printf '%s\n' B1 B2 B3 > right.txt
$ pr -t -m -s' | ' left.txt right.txt
A1 | B1
A2 | B2
A3 | B3

Files are read in parallel, useful for a compact comparison. Shorter files just leave blank space after their last line. By default -m can truncate lines to fit the page width, so if preserving full lines matters more than alignment, check the documented interaction between -J and -m before you settle on a format.

7. Control the heading and page size

Use -h to replace the file name in the header; it changes the label, not the input:

$ printf 'one\ntwo\n' | pr -h 'stdin demo' - | sed -n '1,7p'


2026-09-26 12:01             stdin demo             Page 1


one

Time and spacing vary as before. An empty header, -h '', is documented as producing a blank line, but the manual itself advises against that form. Reach for -t instead when you just do not want headers.

-l sets the page length. Values of 10 or fewer imply -t automatically, which is handy for a short, predictable block of output:

$ pr -l 10 input.txt
alpha
bravo
charlie
delta
echo
foxtrot

For ordinary printing, leave the default page length alone unless the printer or downstream formatter genuinely needs another size. A very small value changes the header behaviour too, which can be more distraction than help.

8. Preview before replacing an existing file

For any output that matters, write to a new file first. That way a wrong path, option or permission does not cost you the old result:

$ pr -t -n input.txt > formatted.txt.new
$ test -s formatted.txt.new && sed -n '1,3p' formatted.txt.new
    1	alpha
    2	bravo
    3	charlie
$ mv formatted.txt.new formatted.txt

mv is the point of no return here: it replaces the destination if one already exists. Run it only once the preview checks out. If the preview is wrong, leave the original alone and clear up the unneeded .new file yourself. Do not reach for sudo to paper over an uncertain path; fix the ownership or permissions on purpose, and only on a directory you actually administer.

Common traps

File will not open. Check the path and readability without changing anything:

$ ls -l /path/to/input.txt
$ test -r /path/to/input.txt && echo readable
readable
  • Long lines look cut off. Check whether -W, a column option, or the default 72-character width is truncating output. Use -J when you need full lines joined, but expect the result to lose column alignment.
  • Existing pagination in the input. Choose -t or -T depending on whether the existing form feeds should stay.

Scripting against pr. Check the exit status immediately after the call:

$ pr -t input.txt > formatted.txt
$ printf 'pr status: %s\n' "$?"
pr status: 0

A zero status only means the command completed. It proves nothing about whether the layout suits the printer, whether long lines got truncated, or whether the output file is even the one you meant to write. Look at a representative page or two before sending a large job to a real printer.

Done means

  • Version identified. pr --version confirmed which implementation you are running.
  • Format matches the job. Headers, line numbers, columns or merged files were chosen for the actual output you need.
  • Width and pagination checked. Long lines and any existing form feeds are handled on purpose, not by accident.
  • Output previewed. The formatted result was checked before any existing file was replaced.
  • Sources untouched. Input files are unchanged, and no elevated privileges were used without a clear permissions reason.