Display two files side by side

2019-01-16 03:50发布

How can 2 unsorted text files of different lengths be display side by side (in columns) in a 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 column 1 and 2. I know how to this with emacs and vim but want the output displayed to stdout for piping ect.

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

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

I could create a function and stick it in my .bashrc but surely a command for this exists already (or a cleaner solution potentially)?

9条回答
放我归山
2楼-- · 2019-01-16 04:11

Find below a 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
查看更多
欢心
3楼-- · 2019-01-16 04:21
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 a format specification allows you to supply the field length dynamically.

查看更多
Bombasti
4楼-- · 2019-01-16 04:25

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

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

Most shell's will store (and update) your terminal's screenwidth in the $COLUMNS environment variable, so we're just passing that value on to pr to use for its output's width setting.

This also answers @Matt's question:

Is there a way for pr to auto-detect screen width?

So, no: pr itself can't detect the screenwidth, but we're helping out a bit by passing in the terminal's width via the -w option.

查看更多
登录 后发表回答