Paginate or columnate FILE(s) for printing.
As stated in the above quote from the manual, the
pr command is mainly used for those two tasks. This book will discuss only the columnate features and some miscellaneous tasks.
Here's a pagination example if you are interested in exploring further. The
pr command will add blank lines, a header and so on to make it suitable for printing.
$ pr greeting.txt | head 2021-08-05 14:10 greeting.txt Page 1 Hi there Have a nice day
-a options can be used to merge the input lines in two different ways:
- split the input file and then merge them as columns
- merge consecutive lines, similar to the
Here's an example to get started. Note that
-N is same as using
N is the number of columns you want in the output. The default page width is
72, which means each column can only have a maximum of
72/N characters (including the separator). Tab and space characters will be used to fill the columns as needed. You can use the
-J option to prevent
pr from truncating longer columns. The
-t option is used here to turn off the pagination features.
# split input into three parts # each column width is 72/3 = 24 characters max $ seq 9 | pr -3t 1 4 7 2 5 8 3 6 9
You can customize the separator using the
-s option. The default is a tab character which you can change to any other string value. The
-s option also turns off line truncation, so
-J option isn't needed. However, the default page width of
72 can still cause issues, which will be discussed later.
# tab separator $ seq 9 | pr -3ts 1 4 7 2 5 8 3 6 9 # comma separator $ seq 9 | pr -3ts, 1,4,7 2,5,8 3,6,9 # multicharacter separator $ seq 9 | pr -3ts' : ' 1 : 4 : 7 2 : 5 : 8 3 : 6 : 9
-a option to merge consecutive lines, similar to the
paste command. One advantage is that the
-s option supports a string value, whereas with
paste you'd need to use workarounds to get multicharacter separation.
# four consecutive lines are merged # same as: paste -d: - - - - $ seq 8 | pr -4ats: 1:2:3:4 5:6:7:8
There are other differences between the
paste commands as well. Unlike
pr command doesn't add the separator if the last row doesn't have enough columns. Another difference is that
pr doesn't support an option to use the NUL character as the line separator.
$ seq 10 | pr -4ats, 1,2,3,4 5,6,7,8 9,10 $ seq 10 | paste -d, - - - - 1,2,3,4 5,6,7,8 9,10,,
As mentioned before, the default page width is
72. This can cause lines to be truncated, unless
-J options are used. There's another issue you might run into, for example:
$ seq 100 | pr -50ats, pr: page width too narrow
(N-1)*length(separator) + N is the minimum page width you need, where
N is the number of columns required. So, for
50 columns and a separator of length
1, you'll need a minimum width of
99. This calculation doesn't make any assumption about the size of input lines, so you may need
-J to ensure input lines aren't truncated.
You can use the
-w option to change the page width. The
-w option overrides the effect of
-s option on line truncation, so use
-J option as well unless you really need truncation. If truncation is active, maximum column width is
(PageWidth - (N-1)*length(separator)) / N rounded down to an integer value. Here's some examples:
# minimum width needed is 3 for N=2 and length=1 # maximum column width: (6 - 1) / 2 = 2 $ pr -w6 -2ts, greeting.txt Hi,Ha # use -J to avoid truncation $ pr -J -w6 -2ts, greeting.txt Hi there,Have a nice day # N=3 and length=4, so minimum width needed is (3-1)*4 + 3 = 11 $ seq 6 | pr -J -w10 -3ats'::::' pr: page width too narrow $ seq 6 | pr -J -w11 -3ats'::::' 1::::2::::3 4::::5::::6 # you can also use a large number to avoid having to calculate the width $ seq 6 | pr -J -w500 -3ats'::::' 1::::2::::3 4::::5::::6
Two or more input files can be merged column wise using the
-m option. As seen before,
-t is needed to ignore pagination features and
-s can be used to customize the separator.
# same as: paste colors_1.txt colors_2.txt $ pr -mts colors_1.txt colors_2.txt Blue Black Brown Blue Orange Green Purple Orange Red Pink Teal Red White White # same as: paste -d' : ' <(seq 3) /dev/null /dev/null <(seq 4 6) $ pr -mts' : ' <(seq 3) <(seq 4 6) 1 : 4 2 : 5 3 : 6
You can prefix the output with line numbers using the
-n option. By default, this option supports up to
5 digit numbers and uses the tab character to separate the numbering and line contents. You can optionally pass two arguments to this option — maximum number of digits and the separator character. If both arguments are used, the separator should be specified first. If you want to customize the starting line number, use the
-N option as well.
# maximum of 1 digit for numbering # use : as the separator between line number and line contents $ pr -n:1 -mts, colors_1.txt colors_2.txt 1:Blue,Black 2:Brown,Blue 3:Orange,Green 4:Purple,Orange 5:Red,Pink 6:Teal,Red 7:White,White
The string passed to
-s is treated literally. Depending on your shell you can use ANSI-C quoting to allow escape sequences. Unlike columnate, the separator is added even if the data is missing for some of the files.
# greeting.txt has 2 lines # fruits.txt has 3 lines # same as: paste -d$'\n' greeting.txt fruits.txt $ pr -mts$'\n' greeting.txt fruits.txt Hi there banana Have a nice day papaya mango
You can use the
-d option to double space the input contents. That is, every newline character is doubled.
$ pr -dt fruits.txt banana papaya mango
-v option will convert non-printing characters like carriage return, backspace, etc to their octal representations (
$ printf 'car\bt\r\nbike\0p\r\n' | pr -vt car\010t\015 bike\000p\015
pr -t is a roundabout way of concatenating input files. But one advantage is that this will add a newline character at the end if not present in the input.
# 'cat' will not add a newline character # so, use 'pr' if newline is needed at the end $ printf 'a\nb\nc' | pr -t a b c