Display two files side by side

How two unsorted text files of different lengths will be displayed side by side (in columns) in the shell

Given one.txt and two.txt :

 $ cat one.txt apple pear longer line than the last two last line $ cat two.txt The quick brown fox.. foo bar linux skipped a line 

Display:

 apple The quick brown fox.. pear foo longer line than the last two bar last line linux skipped a line 

paste one.txt two.txt almost does the trick, but doesn't align the columns nicely, as it just prints one tab between columns 1 and 2. I know how to do this with emacs and vim, but I want the output to be output to stdout for pipeline ect.

The solution I came up with uses sdiff and then goes to sed to remove the sdiff output.

sdiff one.txt two.txt | sed -r 's/[<>|]//;s/(\t){3}//'

I could create a function and paste it into my .bashrc , but of course there is already a command for this (or a potential solution for cleaning)?

+78
command-line linux unix shell gnu-coreutils
Nov 12 '12 at 10:15
source share
9 answers

To do this, you can use pr , using the -m flag to merge files, one per column, and -t for -t headers, for example.

 pr -m -t one.txt two.txt 

outputs:

 apple The quick brown fox.. pear foo longer line than the last two bar last line linux skipped a line 

See also:

+139
Nov 12 '12 at 12:44
source share

To expand on @Hasturkun's answer a bit : by default, pr uses only 72 columns for output, but it’s relatively easy to use all available columns of your terminal window:

 pr -w $COLUMNS -m -t one.txt two.txt 

In most cases, the shell will save (and update) the screen width of your terminal in the $COLUMNS environment $COLUMNS , so we just pass this value to pr to use its output width setting.

This also answers @Matt's question:

Is there a way to automatically detect screen width?

So, no: pr cannot determine the width of the screen itself, but we help a bit by skipping the width in the terminal using the -w option.

+25
May 08 '14 at 1:40
source share
 paste one.txt two.txt | awk -F'\t' '{ if (length($1)>max1) {max1=length($1)}; col1[NR] = $1; col2[NR] = $2 } END {for (i = 1; i<=NR; i++) {printf ("%-*s %s\n", max1, col1[i], col2[i])} }' 

Using * in the format specification allows you to dynamically set the field length.

+6
Nov 12
source share

If you know that the input files have no tabs, using expand makes @oyss's answer easier

 paste one.txt two.txt | expand --tabs=50 

If there may be tabs in the input files, you can always expand first:

 paste <(expand one.txt) <(expand two.txt) | expand --tabs=50 
+5
Aug 25 '15 at 6:11
source share

removing the dynamic field length based on Barmar's answer will make it a much shorter command .... but you still need at least one script to complete a job that you couldn’t avoid, no matter which method you choose.

 paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$2)}' 
+2
Nov 12 '12 at 12:17
source share

There is a sed method:

 f1width=$(wc -L <one.txt) f1blank="$(printf "%${f1width}s" "")" paste one.txt two.txt | sed " s/^\(.*\)\t/\1$f1blank\t/; s/^\(.\{$f1width\}\) *\t/\1 /; " 

(Of course, @Hasturkun pr solution is the most accurate !) :

+1
Jan 04 '13 at 14:43
source share

If you want to know the real difference between the two files side by side, use diff -y :

 diff -y file1.cf file2.cf 

You can also set the output width using -W, --Width=NUM :

 diff -y -W 150 file1.cf file2.cf 

and so that the output of the diff column matches the current terminal window:

 diff -y -W $COLUMNS file1.cf file2.cf 
+1
Jan 12 '15 at 10:12
source share
 diff -y <file1> <file2> [root /]# cat /one.txt 
 apple
 pear
 longer line than the last two
 last line
 [root /]# cat /two.txt 
 The quick brown fox ..
 foo
 bar
 linux
 [root@RHEL6-64 /]# diff -y one.txt two.txt 
 apple |  The quick brown fox ..
 pear |  foo
 longer line than the last two |  bar
 last line |  linux
0
Jan 01
source share

Find below python based solution.

 import sys # Specify the number of spaces between the columns S = 4 # Read the first file l0 = open( sys.argv[1] ).read().split('\n') # Read the second file l1 = open( sys.argv[2] ).read().split('\n') # Find the length of the longest line of the first file n = len(max(l0, key=len)) # Print the lines for i in xrange( max( len(l0), len(l1) ) ): try: print l0[i] + ' '*( n - len(l0[i]) + S) + l1[i] except: try: print ' ' + ' '*( n - 1 + S) + l1[i] except: print l0[i] 

Example

 apple The quick brown fox.. pear foo longer line than the last two bar last line linux skipped a line 
0
Jan 29 '16 at 15:01
source share



All Articles