7

I want to output two text files in two columns — one on the left side and other one on the right.

paste doesn't solve the problem, because it only insert a character as delimiter, so if the first file has lines of different lengths output will be twisted:

$ cat file1
looooooooong line
line
$ cat file2
hello
world
$ paste file1 file2
looooooooong line   hello
line    world

If there was a command to add trailing spaces like fmt --add-spaces --width 50 the problem would be solved(1):

$ paste <(fmt --add-spaces --width 50 file1) file2
looooooooong line                                 hello
line                                              world

But I don't know a simple way to do this.

So how to merge files horizontally and print them to standard output without twisting?

In fact I just want to read them side-by-side.


(1) UPD: command to add trailing spaces does exist, e. g. xargs -d '\n' printf '%-50s\n'. But running
$ paste <(add-trailing-spaces file1) file2 won't produce expected visual output when file1 has fewer lines than file2.

belkka
  • 481

4 Answers4

12

With single pr command:

pr -Tm file[12]
  • -T (--omit-pagination) - omit page headers and trailers, eliminate any pagination by form feeds set in input files

  • -m (--merge) - print all files in parallel, one in each column

9

What about paste file{1,2}| column -s $'\t' -tn?

looooooooong line line  hello
line                    world
  • This is telling column to use Tab as columns' separator where we takes it from the paste command which is the default seperator there if not specified; generally:

    paste -d'X' file{1,2}| column -s $'X' -tn

    where X means any single character. You need to choose the one which granted that won't be occur in your files.

  • The -t option is used to determine the number of columns the input contains.

  • This will not add long tab between two files while other answers does.
  • this will work even if there was empty line(s) in file1 and it will not print second file in print area of file1, see below input/ouput

    Input file1:

    looooooooong line
    
    line
    

    Input file2:

    hello
    world
    

    Output:

    looooooooong line  hello
                       world
    line
    
αғsнιη
  • 41,407
  • 1
    Generally paste -d @ file1 file2 | column -t -n -s @ where @ is any delimiter that is not contained in files. – belkka Sep 16 '17 at 18:46
  • @belkka exactly – αғsнιη Jul 28 '18 at 18:02
  • I had been trying this but without the $. This is the answer for me, but could you explain what the $ is doing here? – paradroid Sep 27 '19 at 16:55
  • 1
    @paradroid please see https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html – αғsнιη Sep 27 '19 at 17:11
  • I get -n requires an argument. Isn't that used for naming the table? – einpoklum Nov 29 '22 at 10:22
  • @einpoklum my column command man page says -n By default, the column command will merge multiple adjacent delimiters into a single delimiter when us‐ ing the -t option; this option disables that behavior. This option is a Debian GNU/Linux extension. – αғsнιη Nov 29 '22 at 11:33
  • @αғsнιη: And are you sure it's a good idea for your answer to require being on Debian? I mean, don't get me wrong, that's what I have at home,, but not all Linux/Unix systems are Debian. At least comment about this assumption in your answer. – einpoklum Nov 29 '22 at 11:38
1

A portable solution:

$ paste file1 file2 | awk -F'\t' '{ printf("%-30s %s\n", $1, $2) }'
looooooooong line              hello
line                           world

This uses paste to produce a tab-delimited input for awk.

The awk script simply takes the two tab-delimited fields and outputs them using printf(). A column of 30 characters is reserved for the first file. The %-30s means "30 positions of string data with left alignment". Removing the - would produce a column aligned to the right, and changing 30 would change the column width.

It also deals with uneven length files. Here I've added lines to the second file:

looooooooong line              hello
line                           world
                               hello
                               world
                               hello
                               world

And, when reversing the order of the files on the command line:

hello                          looooooooong line
world                          line
hello
world
hello
world
Kusalananda
  • 333,661
1

Try:

paste -d '\n' file1 file2 | xargs -d '\n' printf '%-30s  %-30s\n'

Inspired by @Kusalananda's solution.

Note: The -d parameter of xargs is only available on GNU version, but not on BSD.

kenorb
  • 20,988
belkka
  • 481