Restructure text

Table of Contents


paste

$ paste --version | head -n1
paste (GNU coreutils) 8.25

$ man paste
PASTE(1)                         User Commands                        PASTE(1)

NAME
       paste - merge lines of files

SYNOPSIS
       paste [OPTION]... [FILE]...

DESCRIPTION
       Write  lines  consisting  of  the sequentially corresponding lines from
       each FILE, separated by TABs, to standard output.

       With no FILE, or when FILE is -, read standard input.
...


Concatenating files column wise

  • By default, paste adds a TAB between corresponding lines of input files
$ paste colors_1.txt colors_2.txt
Blue    Black
Brown   Blue
Purple  Green
Red     Red
Teal    White
  • Specifying a different delimiter using -d
  • The <() syntax is Process Substitution
    • to put it simply - allows output of command to be passed as input file to another command without needing to manually create a temporary file
$ paste -d, <(seq 5) <(seq 6 10)
1,6
2,7
3,8
4,9
5,10

$ # empty cells if number of lines is not same for all input files
$ # -d\| can also be used
$ paste -d'|' <(seq 3) <(seq 4 6) <(seq 7 10)
1|4|7
2|5|8
3|6|9
||10
  • to paste without any character in between, use \0 as delimiter
    • note that \0 here doesn't mean the ASCII NUL character
    • can also use -d '' with GNU paste
$ paste -d'\0' <(seq 3) <(seq 6 8)
16
27
38


Interleaving lines

  • Interleave lines by using newline as delimiter
$ paste -d'\n' <(seq 11 13) <(seq 101 103)
11
101
12
102
13
103


Lines to multiple columns

  • Number of - specified determines number of output columns
  • Input lines can be passed only as stdin
$ # single column to two columns
$ seq 10 | paste -d, - -
1,2
3,4
5,6
7,8
9,10

$ # single column to five columns
$ seq 10 | paste -d: - - - - -
1:2:3:4:5
6:7:8:9:10

$ # input redirection for file input
$ paste -d, - - < colors_1.txt
Blue,Brown
Purple,Red
Teal,
  • Use printf trick if number of columns to specify is too large
$ # prompt at end of line not shown for simplicity
$ printf -- "- %.s" {1..5}
- - - - - 

$ seq 10 | paste -d, $(printf -- "- %.s" {1..5})
1,2,3,4,5
6,7,8,9,10


Different delimiters between columns

  • For more than 2 columns, different delimiter character can be specified - passed as list to -d option
$ # , is used between 1st and 2nd column
$ # - is used between 2nd and 3rd column
$ paste -d',-' <(seq 3) <(seq 4 6) <(seq 7 9)
1,4-7
2,5-8
3,6-9

$ # re-use list from beginning if not specified for all columns
$ paste -d',-' <(seq 3) <(seq 4 6) <(seq 7 9) <(seq 10 12)
1,4-7,10
2,5-8,11
3,6-9,12
$ # another example
$ seq 10 | paste -d':,' - - - - -
1:2,3:4,5
6:7,8:9,10

$ # so, with single delimiter, it is just re-used for all columns
$ paste -d, <(seq 3) <(seq 4 6) <(seq 7 9) <(seq 10 12)
1,4,7,10
2,5,8,11
3,6,9,12
  • combination of -d and /dev/null (empty file) can give multi-character separation between columns
  • If this is too confusing to use, consider pr instead
$ paste -d' : ' <(seq 3) /dev/null /dev/null <(seq 4 6) /dev/null /dev/null <(seq 7 9)
1 : 4 : 7
2 : 5 : 8
3 : 6 : 9

$ # or just use pr instead
$ pr -mts' : ' <(seq 3) <(seq 4 6) <(seq 7 9)
1 : 4 : 7
2 : 5 : 8
3 : 6 : 9

$ # but paste would allow different delimiters ;)
$ paste -d' :  - ' <(seq 3) /dev/null /dev/null <(seq 4 6) /dev/null /dev/null <(seq 7 9)
1 : 4 - 7
2 : 5 - 8
3 : 6 - 9

$ # pr would need two invocations
$ pr -mts' : ' <(seq 3) <(seq 4 6) | pr -mts' - ' - <(seq 7 9)
1 : 4 - 7
2 : 5 - 8
3 : 6 - 9
  • example to show using empty file instead of /dev/null
$ # assuming file named e doesn't exist
$ touch e
$ # or use this, will empty contents even if file named e already exists :P
$ > e

$ paste -d' :  - ' <(seq 3) e e <(seq 4 6) e e <(seq 7 9)
1 : 4 - 7
2 : 5 - 8
3 : 6 - 9


Multiple lines to single row

$ paste -sd, colors_1.txt
Blue,Brown,Purple,Red,Teal

$ # multiple files each gets a row
$ paste -sd: colors_1.txt colors_2.txt
Blue:Brown:Purple:Red:Teal
Black:Blue:Green:Red:White

$ # multiple input files need not have same number of lines
$ paste -sd, <(seq 3) <(seq 5 9)
1,2,3
5,6,7,8,9
  • Often used to serialize multiple line output from another command
$ sort -u colors_1.txt colors_2.txt | paste -sd,
Black,Blue,Brown,Green,Purple,Red,Teal,White
  • For multiple character delimiter, post-process if separator is unique or use another tool like perl
$ seq 10 | paste -sd,
1,2,3,4,5,6,7,8,9,10

$ # post-process
$ seq 10 | paste -sd, | sed 's/,/ : /g'
1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10

$ # using perl alone
$ seq 10 | perl -pe 's/\n/ : / if(!eof)'
1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10


Further reading for paste


column

COLUMN(1)                 BSD General Commands Manual                COLUMN(1)

NAME
     column — columnate lists

SYNOPSIS
     column [-entx] [-c columns] [-s sep] [file ...]

DESCRIPTION
     The column utility formats its input into multiple columns.  Rows are
     filled before columns.  Input is taken from file operands, or, by
     default, from the standard input.  Empty lines are ignored unless the -e
     option is used.
...


Pretty printing tables

  • by default whitespace is input delimiter
$ cat dishes.txt
North alootikki baati khichdi makkiroti poha
South appam bisibelebath dosa koottu sevai
West dhokla khakhra modak shiro vadapav
East handoguri litti momo rosgulla shondesh

$ column -t dishes.txt
North  alootikki  baati         khichdi  makkiroti  poha
South  appam      bisibelebath  dosa     koottu     sevai
West   dhokla     khakhra       modak    shiro      vadapav
East   handoguri  litti         momo     rosgulla   shondesh
  • often useful to get neatly aligned columns from output of another command
$ paste fruits.txt price.txt
Fruits  Price
apple   182
guava   90
watermelon      35
banana  72
pomegranate     280

$ paste fruits.txt price.txt | column -t
Fruits       Price
apple        182
guava        90
watermelon   35
banana       72
pomegranate  280


Specifying different input delimiter

  • Use -s to specify input delimiter
  • Use -n to prevent merging empty cells
    • From man column "This option is a Debian GNU/Linux extension"
$ paste -d, <(seq 3) <(seq 5 9) <(seq 11 13)
1,5,11
2,6,12
3,7,13
,8,
,9,

$ paste -d, <(seq 3) <(seq 5 9) <(seq 11 13) | column -s, -t
1  5  11
2  6  12
3  7  13
8
9

$ paste -d, <(seq 3) <(seq 5 9) <(seq 11 13) | column -s, -nt
1  5  11
2  6  12
3  7  13
   8  
   9


Further reading for column


pr

$ pr --version | head -n1
pr (GNU coreutils) 8.25

$ man pr
PR(1)                            User Commands                           PR(1)

NAME
       pr - convert text files for printing

SYNOPSIS
       pr [OPTION]... [FILE]...

DESCRIPTION
       Paginate or columnate FILE(s) for printing.

       With no FILE, or when FILE is -, read standard input.
...
  • Paginate is not covered, examples related only to columnate
  • For example, default invocation on a file would add a header, etc
$ # truncated output shown
$ pr fruits.txt


2017-04-21 17:49                    fruits.txt                    Page 1


Fruits
apple
guava
watermelon
banana
pomegranate
  • Following sections will use -t to omit page headers and trailers


Converting lines to columns

  • With paste, changing input file rows to column(s) is possible only with consecutive lines
  • pr can do that as well as split entire file itself according to number of columns needed
  • And -s option in pr allows multi-character output delimiter
  • As usual, examples to better show the functionalities
$ # note how the input got split into two and resulting splits joined by ,
$ seq 6 | pr -2ts,
1,4
2,5
3,6

$ # note how two consecutive lines gets joined by ,
$ seq 6 | paste -d, - -
1,2
3,4
5,6
  • Default PAGE_WIDTH is 72 characters, so each column gets 72 divided by number of columns unless -s is used
$ # 3 columns, so each column width is 24 characters
$ seq 9 | pr -3t
1                       4                       7
2                       5                       8
3                       6                       9

$ # using -s, desired delimiter can be specified
$ seq 9 | pr -3ts' '
1 4 7
2 5 8
3 6 9

$ seq 9 | pr -3ts' : '
1 : 4 : 7
2 : 5 : 8
3 : 6 : 9

$ # default is TAB when using -s option with no arguments
$ seq 9 | pr -3ts
1       4       7
2       5       8
3       6       9
  • Using -a to change consecutive rows, similar to paste
$ seq 8 | pr -4ats:
1:2:3:4
5:6:7:8

$ # no output delimiter for empty cells
$ seq 22 | pr -5ats,
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22

$ # note output delimiter even for empty cells
$ seq 22 | paste -d, - - - - -
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,,,


Changing PAGE_WIDTH

  • The default PAGE_WIDTH is 72
  • The formula (col-1)*len(delimiter) + col seems to work in determining minimum PAGE_WIDTH required for multiple column output
    • col is number of columns required
$ # (36-1)*1 + 36 = 71, so within PAGE_WIDTH limit
$ seq 74 | pr -36ats,
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
$ # (37-1)*1 + 37 = 73, more than default PAGE_WIDTH limit
$ seq 74 | pr -37ats,
pr: page width too narrow
  • Use -w to specify a different PAGE_WIDTH
  • The -J option turns off truncation
$ # (37-1)*1 + 37 = 73
$ seq 74 | pr -J -w73 -37ats,
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

$ # (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

$ # if calculating is difficult, simply use a large number
$ seq 6 | pr -J -w500 -3ats'::::'
1::::2::::3
4::::5::::6


Combining multiple input files

  • Use -m option to combine multiple files in parallel, similar to paste
$ # 2 columns, so each column width is 36 characters
$ pr -mt fruits.txt price.txt
Fruits                              Price
apple                               182
guava                               90
watermelon                          35
banana                              72
pomegranate                         280

$ # default is TAB when using -s option with no arguments
$ pr -mts <(seq 3) <(seq 4 6) <(seq 7 10)
1       4       7
2       5       8
3       6       9
                10

$ # double TAB as separator
$ # shell expands $'\t\t' before command is executed
$ pr -mts$'\t\t' colors_1.txt colors_2.txt
Blue            Black
Brown           Blue
Purple          Green
Red             Red
Teal            White
  • For interleaving, specify newline as separator
$ pr -mts$'\n' fruits.txt price.txt
Fruits
Price
apple
182
guava
90
watermelon
35
banana
72
pomegranate
280


Transposing a table

$ # delimiter is single character, so easy to use tr to change it to newline
$ cat dishes.txt
North alootikki baati khichdi makkiroti poha
South appam bisibelebath dosa koottu sevai
West dhokla khakhra modak shiro vadapav
East handoguri litti momo rosgulla shondesh

$ # 4 columns, so each column width is 18 characters
$ # $(wc -l < dishes.txt) gives number of columns required
$ tr ' ' '\n' < dishes.txt | pr -$(wc -l < dishes.txt)t
North             South             West              East
alootikki         appam             dhokla            handoguri
baati             bisibelebath      khakhra           litti
khichdi           dosa              modak             momo
makkiroti         koottu            shiro             rosgulla
poha              sevai             vadapav           shondesh
  • Pipe the output to column if spacing is too much
$ tr ' ' '\n' < dishes.txt | pr -$(wc -l < dishes.txt)t | column -t
North      South         West     East
alootikki  appam         dhokla   handoguri
baati      bisibelebath  khakhra  litti
khichdi    dosa          modak    momo
makkiroti  koottu        shiro    rosgulla
poha       sevai         vadapav  shondesh


Further reading for pr

  • man pr and info pr for more options and detailed documentation
  • More examples here


fold

$ fold --version | head -n1
fold (GNU coreutils) 8.25

$ man fold
FOLD(1)                          User Commands                         FOLD(1)

NAME
       fold - wrap each input line to fit in specified width

SYNOPSIS
       fold [OPTION]... [FILE]...

DESCRIPTION
       Wrap input lines in each FILE, writing to standard output.

       With no FILE, or when FILE is -, read standard input.
...


Examples

$ nl story.txt
     1    The princess of a far away land fought bravely to rescue a travelling group from bandits. And the happy story ends here. Have a nice day.
     2    Still here? okay, read on: The prince of Happalakkahuhu wished he could be as brave as his sister and vowed to train harder

$ # default folding width is 80
$ fold story.txt
The princess of a far away land fought bravely to rescue a travelling group from
 bandits. And the happy story ends here. Have a nice day.
Still here? okay, read on: The prince of Happalakkahuhu wished he could be as br
ave as his sister and vowed to train harder

$ fold story.txt | nl
     1    The princess of a far away land fought bravely to rescue a travelling group from
     2     bandits. And the happy story ends here. Have a nice day.
     3    Still here? okay, read on: The prince of Happalakkahuhu wished he could be as br
     4    ave as his sister and vowed to train harder
  • -s option breaks at spaces to avoid word splitting
$ fold -s story.txt
The princess of a far away land fought bravely to rescue a travelling group 
from bandits. And the happy story ends here. Have a nice day.
Still here? okay, read on: The prince of Happalakkahuhu wished he could be as 
brave as his sister and vowed to train harder
  • Use -w to change default width
$ fold -s -w60 story.txt
The princess of a far away land fought bravely to rescue a 
travelling group from bandits. And the happy story ends 
here. Have a nice day.
Still here? okay, read on: The prince of Happalakkahuhu 
wished he could be as brave as his sister and vowed to 
train harder


Further reading for fold

  • man fold and info fold for more options and detailed documentation

results matching ""

    No results matching ""