-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathpr.html
182 lines (160 loc) · 19.3 KB
/
pr.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<!doctypehtml><html class="sidebar-visible no-js light"lang=en><head><meta charset=UTF-8><title>pr - CLI text processing with GNU Coreutils</title><meta content="text/html; charset=utf-8"http-equiv=Content-Type><meta content="Example based guide for specialized text processing with GNU Coreutils"name=description><meta content=width=device-width,initial-scale=1 name=viewport><meta content=#ffffff name=theme-color><meta content="CLI text processing with GNU Coreutils"property=og:title><meta content=website property=og:type><meta content="Example based guide for specialized text processing with GNU Coreutils"property=og:description><meta content=https://learnbyexample.github.io/cli_text_processing_coreutils/ property=og:url><meta content=https://raw.githubusercontent.com/learnbyexample/cli_text_processing_coreutils/main/images/cli_coreutils_ls.png property=og:image><meta content=1280 property=og:image:width><meta content=720 property=og:image:height><meta content=summary_large_image property=twitter:card><meta content=@learn_byexample property=twitter:site><link href=favicon.svg rel=icon><link rel="shortcut icon"href=favicon.png><link href=css/variables.css rel=stylesheet><link href=css/general.css rel=stylesheet><link href=css/chrome.css rel=stylesheet><link href=FontAwesome/css/font-awesome.css rel=stylesheet><link href=fonts/fonts.css rel=stylesheet><link href=highlight.css rel=stylesheet><link href=tomorrow-night.css rel=stylesheet><link href=ayu-highlight.css rel=stylesheet><link href=style.css rel=stylesheet><body><script>var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";</script><script>try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }</script><script>var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');</script><script>var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);</script><nav aria-label="Table of contents"class=sidebar id=sidebar><div class=sidebar-scrollbox><ol class=chapter><li class="chapter-item expanded affix"><a href=cover.html>Cover</a><li class="chapter-item expanded affix"><a href=buy.html>Buy PDF/EPUB versions</a><li class="chapter-item expanded affix"><a href=preface.html>Preface</a><li class="chapter-item expanded"><a href=introduction.html><strong aria-hidden=true>1.</strong> Introduction</a><li class="chapter-item expanded"><a href=cat-tac.html><strong aria-hidden=true>2.</strong> cat and tac</a><li class="chapter-item expanded"><a href=head-tail.html><strong aria-hidden=true>3.</strong> head and tail</a><li class="chapter-item expanded"><a href=tr.html><strong aria-hidden=true>4.</strong> tr</a><li class="chapter-item expanded"><a href=cut.html><strong aria-hidden=true>5.</strong> cut</a><li class="chapter-item expanded"><a href=seq.html><strong aria-hidden=true>6.</strong> seq</a><li class="chapter-item expanded"><a href=shuf.html><strong aria-hidden=true>7.</strong> shuf</a><li class="chapter-item expanded"><a href=paste.html><strong aria-hidden=true>8.</strong> paste</a><li class="chapter-item expanded"><a class=active href=pr.html><strong aria-hidden=true>9.</strong> pr</a><li class="chapter-item expanded"><a href=fold-fmt.html><strong aria-hidden=true>10.</strong> fold and fmt</a><li class="chapter-item expanded"><a href=sort.html><strong aria-hidden=true>11.</strong> sort</a><li class="chapter-item expanded"><a href=uniq.html><strong aria-hidden=true>12.</strong> uniq</a><li class="chapter-item expanded"><a href=comm.html><strong aria-hidden=true>13.</strong> comm</a><li class="chapter-item expanded"><a href=join.html><strong aria-hidden=true>14.</strong> join</a><li class="chapter-item expanded"><a href=nl.html><strong aria-hidden=true>15.</strong> nl</a><li class="chapter-item expanded"><a href=wc.html><strong aria-hidden=true>16.</strong> wc</a><li class="chapter-item expanded"><a href=split.html><strong aria-hidden=true>17.</strong> split</a><li class="chapter-item expanded"><a href=csplit.html><strong aria-hidden=true>18.</strong> csplit</a><li class="chapter-item expanded"><a href=expand-unexpand.html><strong aria-hidden=true>19.</strong> expand and unexpand</a><li class="chapter-item expanded"><a href=basename-dirname.html><strong aria-hidden=true>20.</strong> basename and dirname</a><li class="chapter-item expanded affix"><a href=what_next.html>What next?</a><li class="chapter-item expanded affix"><a href=Exercise_solutions.html>Exercise solutions</a></li><br><hr><li class="chapter-item expanded"><i class="fa fa-github"id=git-repository-button></i><a href=https://github.com/learnbyexample/cli_text_processing_coreutils> Source code</a><li class="chapter-item expanded"><i class="fa fa-home"id=home-button></i><a href=https://learnbyexample.github.io/> My Blog</a><li class="chapter-item expanded"><i class="fa fa-book"id=book-button></i><a href=https://learnbyexample.github.io/books/> My Books</a><li class="chapter-item expanded"><i class="fa fa-envelope"id=mail-button></i><a href=https://learnbyexample.gumroad.com/l/learnbyexample-weekly> learnbyexample weekly</a><li class="chapter-item expanded"><i class="fa fa-twitter"id=twitter-button></i><a href=https://twitter.com/learn_byexample> Twitter</a></ol></div><div class=sidebar-resize-handle id=sidebar-resize-handle></div></nav><div class=page-wrapper id=page-wrapper><div class=page><div id=menu-bar-hover-placeholder></div><div class="menu-bar sticky bordered"id=menu-bar><div class=left-buttons><button aria-label="Toggle Table of Contents"title="Toggle Table of Contents"aria-controls=sidebar class=icon-button id=sidebar-toggle type=button><i class="fa fa-bars"></i></button><button aria-label="Change theme"title="Change theme"aria-controls=theme-list aria-expanded=false aria-haspopup=true class=icon-button id=theme-toggle type=button><i class="fa fa-paint-brush"></i></button><ul aria-label=Themes class=theme-popup id=theme-list role=menu><li role=none><button class=theme id=light role=menuitem>Light (default)</button><li role=none><button class=theme id=rust role=menuitem>Rust</button><li role=none><button class=theme id=coal role=menuitem>Coal</button><li role=none><button class=theme id=navy role=menuitem>Navy</button><li role=none><button class=theme id=ayu role=menuitem>Ayu</button></ul><button aria-label="Toggle Searchbar"title="Search. (Shortkey: s)"aria-controls=searchbar aria-expanded=false aria-keyshortcuts=S class=icon-button id=search-toggle type=button><i class="fa fa-search"></i></button></div><h1 class=menu-title>CLI text processing with GNU Coreutils</h1><div class=right-buttons><a aria-label=Blog href=https://learnbyexample.github.io title=Blog> <i class="fa fa-home"id=home-button></i> </a><a aria-label=Twitter href=https://twitter.com/learn_byexample title=Twitter> <i class="fa fa-twitter"id=twitter-button></i> </a><a aria-label="Git repository"title="Git repository"href=https://github.com/learnbyexample/cli_text_processing_coreutils> <i class="fa fa-github"id=git-repository-button></i> </a></div></div><div class=hidden id=search-wrapper><form class=searchbar-outer id=searchbar-outer><input placeholder="Search this book ..."aria-controls=searchresults-outer aria-describedby=searchresults-header id=searchbar name=searchbar type=search></form><div class="searchresults-outer hidden"id=searchresults-outer><div class=searchresults-header id=searchresults-header></div><ul id=searchresults></ul></div></div><script>document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});</script><div class=content id=content><main><div class=sidetoc><nav class=pagetoc></nav></div><h1 id=pr><a class=header href=#pr>pr</a></h1><blockquote><p>Paginate or columnate FILE(s) for printing.</blockquote><p>As stated in the above quote from the manual, the <code>pr</code> command is mainly used for those two tasks. This book will discuss only the columnate features and some miscellaneous tasks.<p>Here's a pagination example if you are interested in exploring further. The <code>pr</code> command will add blank lines, a header and so on to make it suitable for printing.<pre><code class=language-bash>$ pr greeting.txt | head
2024-02-26 15:07 greeting.txt Page 1
Hi there
Have a nice day
</code></pre><h2 id=columnate><a class=header href=#columnate>Columnate</a></h2><p>The <code>--columns</code> and <code>-a</code> options can be used to merge the input lines in two different ways:<ul><li>split the input file and then merge them as columns<li>merge consecutive lines, similar to the <code>paste</code> command</ul><p>Here's an example to get started. Note that <code>-N</code> is same as using <code>--columns=N</code> where <code>N</code> is the number of columns you want in the output. The default page width is <code>72</code>, which means each column can only have a maximum of <code>72/N</code> characters (including the separator). Tab and space characters will be used to fill the columns as needed. You can use the <code>-J</code> option to prevent <code>pr</code> from truncating longer columns. The <code>-t</code> option is used here to turn off the pagination features.<pre><code class=language-bash># 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
</code></pre><p>You can customize the separator using the <code>-s</code> option. The default is a tab character which you can change to any other string value. The <code>-s</code> option also turns off line truncation, so the <code>-J</code> option isn't needed. However, the default page width of <code>72</code> can still cause issues, which will be discussed later.<pre><code class=language-bash># 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
</code></pre><p>Use the <code>-a</code> option to merge consecutive lines, similar to the <code>paste</code> command. One advantage is that the <code>-s</code> option supports a string value, whereas with <code>paste</code> you'd need to use workarounds to get multicharacter separation.<pre><code class=language-bash># four consecutive lines are merged
# same as: paste -d: - - - -
$ seq 8 | pr -4ats:
1:2:3:4
5:6:7:8
</code></pre><p>There are other differences between the <code>pr</code> and <code>paste</code> commands as well. Unlike <code>paste</code>, the <code>pr</code> command doesn't add the separator if the last row doesn't have enough columns. Another difference is that <code>pr</code> doesn't support an option to use the NUL character as the line separator.<pre><code class=language-bash>$ 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,,
</code></pre><h2 id=customizing-page-width><a class=header href=#customizing-page-width>Customizing page width</a></h2><p>As mentioned before, the default page width is <code>72</code>. This can cause lines to be truncated, unless the <code>-s</code> or <code>-J</code> options are used. There's another issue you might run into, for example:<pre><code class=language-bash>$ seq 100 | pr -50ats,
pr: page width too narrow
</code></pre><p><code>(N-1)*length(separator) + N</code> is the minimum page width you need, where <code>N</code> is the number of columns required. So, for <code>50</code> columns and a separator of length <code>1</code>, you'll need a minimum width of <code>99</code>. This calculation doesn't make any assumption about the size of input lines, so you may need <code>-J</code> to ensure input lines aren't truncated.<p>You can use the <code>-w</code> option to change the page width. The <code>-w</code> option overrides the effect of <code>-s</code> option on line truncation, so use <code>-J</code> option as well unless you really need truncation. If truncation is active, maximum column width is <code>(PageWidth - (N-1)*length(separator)) / N</code> rounded down to an integer value. Here are some examples:<pre><code class=language-bash># 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 just use a large number to avoid having to calculate the width
$ seq 6 | pr -J -w500 -3ats'::::'
1::::2::::3
4::::5::::6
</code></pre><h2 id=concatenating-files-column-wise><a class=header href=#concatenating-files-column-wise>Concatenating files column wise</a></h2><p>Two or more input files can be merged column wise using the <code>-m</code> option. As seen before, <code>-t</code> is needed to ignore pagination features and <code>-s</code> can be used to customize the separator.<pre><code class=language-bash># 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
</code></pre><p>You can prefix the output with line numbers using the <code>-n</code> option. By default, this option supports up to <code>5</code> 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 <code>-N</code> option as well.<pre><code class=language-bash># maximum of 1 digit for numbering
# use : as the separator between the 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
</code></pre><p>The string passed to <code>-s</code> is treated literally. Depending on your shell you can use <a href=https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html>ANSI-C quoting</a> to allow escape sequences. Unlike columnate, the separator is added even if the data is missing for some of the files.<pre><code class=language-bash># 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
</code></pre><h2 id=miscellaneous><a class=header href=#miscellaneous>Miscellaneous</a></h2><p>You can use the <code>-d</code> option to double space the input contents. That is, every newline character is doubled.<pre><code class=language-bash>$ pr -dt fruits.txt
banana
papaya
mango
</code></pre><p>The <code>-v</code> option will convert non-printing characters like carriage return, backspace, etc to their octal representations (<code>\NNN</code>).<pre><code class=language-bash>$ printf 'car\bt\r\nbike\0p\r\n' | pr -vt
car\010t\015
bike\000p\015
</code></pre><p><code>pr -t</code> 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.<pre><code class=language-bash># '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
</code></pre><h2 id=exercises><a class=header href=#exercises>Exercises</a></h2><blockquote><p><img alt=info src=images/info.svg> The <a href=https://github.com/learnbyexample/cli_text_processing_coreutils/tree/main/exercises>exercises</a> directory has all the files used in this section.</blockquote><p><strong>1)</strong> What does the <code>-t</code> option do?<p><strong>2)</strong> Generate numbers <code>1</code> to <code>16</code> in two different formats as shown below.<pre><code class=language-bash>$ seq -w 16 | ##### add your solution here
01,02,03,04
05,06,07,08
09,10,11,12
13,14,15,16
$ seq -w 16 | ##### add your solution here
01,05,09,13
02,06,10,14
03,07,11,15
04,08,12,16
</code></pre><p><strong>3)</strong> How'd you solve the issue shown below?<pre><code class=language-bash>$ seq 100 | pr -37ats,
pr: page width too narrow
</code></pre><p><strong>4)</strong> Combine the contents of <code>fruits.txt</code> and <code>colors.txt</code> in two different formats as shown below.<pre><code class=language-bash>$ cat fruits.txt
banana
papaya
mango
$ cat colors.txt
deep blue
light orange
blue delight
##### add your solution here
banana : deep blue
papaya : light orange
mango : blue delight
##### add your solution here
1:banana,deep blue
2:papaya,light orange
3:mango,blue delight
</code></pre><p><strong>5)</strong> What does the <code>-d</code> option do?</main><nav aria-label="Page navigation"class=nav-wrapper><a aria-label="Previous chapter"class="mobile-nav-chapters previous"title="Previous chapter"aria-keyshortcuts=Left href=paste.html rel=prev> <i class="fa fa-angle-left"></i> </a><a aria-label="Next chapter"class="mobile-nav-chapters next"title="Next chapter"aria-keyshortcuts=Right href=fold-fmt.html rel=next> <i class="fa fa-angle-right"></i> </a><div style="clear: both"></div></nav></div></div><nav aria-label="Page navigation"class=nav-wide-wrapper><a aria-label="Previous chapter"class="nav-chapters previous"title="Previous chapter"aria-keyshortcuts=Left href=paste.html rel=prev> <i class="fa fa-angle-left"></i> </a><a aria-label="Next chapter"class="nav-chapters next"title="Next chapter"aria-keyshortcuts=Right href=fold-fmt.html rel=next> <i class="fa fa-angle-right"></i> </a></nav></div><script>window.playground_copyable = true;</script><script charset=utf-8 src=elasticlunr.min.js></script><script charset=utf-8 src=mark.min.js></script><script charset=utf-8 src=searcher.js></script><script charset=utf-8 src=clipboard.min.js></script><script charset=utf-8 src=highlight.js></script><script charset=utf-8 src=book.js></script><script src=sidebar.js></script>