Linux 并排显示两个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13341832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:46:06  来源:igfitidea点击:

Display two files side by side

linuxshellunixcommand-linegnu-coreutils

提问by Chris Seymour

How can 2 unsorted text files of different lengths be display side by side (in columns)in a shell

如何在一个文件中并排(按列)显示 2 个不同长度的未排序文本文件shell

Given one.txtand two.txt:

给定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

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.txtalmost 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.

paste one.txt two.txt几乎可以解决问题,但不能很好地对齐列,因为它只是在第 1 列和第 2 列之间打印一个选项卡。我知道如何使用 emacs 和 vim 执行此操作,但希望将输出显示到标准输出以进行管道等。

The solution I came up with uses sdiffand then pipes to sed to remove the output sdiffadds.

我想出的解决方案使用sdiff然后管道到 sed 以删除输出sdiff添加。

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

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

I could create a function and stick it in my .bashrcbut surely a command for this exists already (or a cleanersolution potentially)?

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

采纳答案by Hasturkun

You can use prto do this, using the -mflag to merge the files, one per column, and -tto omit headers, eg.

您可以使用pr-m标志来合并文件,每列一个,并-t省略标题,例如。

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:

也可以看看:

回答by Barmar

paste one.txt two.txt | awk -F'\t' '{
    if (length()>max1) {max1=length()};
    col1[NR] = ; col2[NR] =  }
    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.

使用*的格式规范允许你动态地提供字段长度。

回答by oyss

remove dynamically field length counting from Barmar's answer will make it a much shorter command....but you still need at least one script to finish the work which could not be avoided no matter what method you choose.

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

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

回答by F. Hauri

There is a sedway:

有一个sed办法:

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

(Of course @Hasturkun 's solution pris the most accurate!):

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

回答by iAdhyan

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

回答by pvandenberk

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

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

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

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

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

This also answers @Matt's question:

这也回答了@Matt的问题:

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

pr 有没有办法自动检测屏幕宽度?

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

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

回答by user3498040

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

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

diff -y file1.cf file2.cf

You can also set an output width using the -W, --width=NUMoption:

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

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

and to make diff's column output fit your current terminal window:

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

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

回答by Bob

If you know the input files have no tabs, then using expandsimplifies @oyss's answer:

如果您知道输入文件没有选项卡,则使用expand可简化@oyss答案

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

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

如果输入文件中可能有选项卡,您始终可以先展开:

paste <(expand one.txt) <(expand two.txt) | expand --tabs=50

回答by funk

Find below a python based solution.

在下面找到一个基于 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]

Example

例子

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

                                 skipped a line