并排显示两个文件

时间:2012-11-12 10:15:29

标签: linux shell unix command-line gnu-coreutils

如何在shell

中并排显示2个不同长度的未分类文本文件(在列中)

给定one.txttwo.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

显示:

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几乎可以解决这个问题但是不能很好地对齐列,因为它只是在第1列和第2列之间打印了一个选项卡。我知道如何使用emacs和vim,但希望输出显示为用于管道等的标准配置

我提出的解决方案使用sdiff然后通过管道来sed删除输出sdiff添加。

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

我可以创建一个函数并将其粘贴在我的.bashrc中,但肯定已经存在一个命令(或者可能是 clean 解决方案)?

8 个答案:

答案 0 :(得分:145)

您可以使用pr执行此操作,使用-m标记合并文件,每列一个,-t以省略标题,例如。

pr -m -t one.txt two.txt

输出:

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

                                    skipped a line

另见:

答案 1 :(得分:26)

要扩展@Hasturkun的答案:默认情况下pr仅使用72列作为输出,但使用终端窗口的所有可用列相对容易:

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

大多数shell将在$COLUMNS环境变量中存储(并更新)终端的screenwidth,因此我们只是将该值传递给pr以用于其输出的宽度设置。

这也回答了@Matt的问题:

  

pr有自动检测屏幕宽度的方法吗?

所以,不,pr本身无法检测到屏幕宽度,但我们通过-w选项传递终端的宽度来帮助我们。

答案 2 :(得分:6)

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])}
}'

在格式规范中使用*可以动态提供字段长度。

答案 3 :(得分:2)

从Barmar的答案中移除动态字段长度计数将使它成为一个更短的命令....但是你仍然需要至少一个脚本来完成无论你选择哪种方法都无法避免的工作。

paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$2)}'

答案 4 :(得分:2)

如果您想并排了解两个文件之间的实际差异,请使用diff -y

diff -y file1.cf file2.cf

您还可以使用-W, --width=NUM选项设置输出宽度:

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

并使diff的列输出适合您当前的终端窗口:

diff -y -W $COLUMNS file1.cf file2.cf

答案 5 :(得分:1)

有一种sed方式:

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

(当然@Hasturkun的解决方案pr最准确的!)

答案 6 :(得分:0)

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

答案 7 :(得分:0)

在下面找到基于python的解决方案。

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]

示例

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

                                 skipped a line