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.

1

4 Answers 4

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

3
  • What does the -T do? Commented Sep 16, 2017 at 18:37
  • This can truncate long lines without any warning, but I like it. Commented Sep 16, 2017 at 19:54
  • On my mac I had to use pr -tm file[12]. (minus -t) Commented Oct 15, 2019 at 9:37
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
    
7
  • 1
    Generally paste -d @ file1 file2 | column -t -n -s @ where @ is any delimiter that is not contained in files. Commented Sep 16, 2017 at 18:46
  • @belkka exactly Commented Jul 28, 2018 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? Commented Sep 27, 2019 at 16:55
  • 1
    @paradroid please see gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html Commented Sep 27, 2019 at 17:11
  • I get -n requires an argument. Isn't that used for naming the table? Commented Nov 29, 2022 at 10:22
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
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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.