web-dev-qa-db-ja.com

2つのファイルを並べて表示する

異なる長さの2つの並べ替えられていないテキストファイルを並べて(列内)Shellに表示する方法

与えられた_one.txt_および_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
_

表示:

_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の間に1つのタブを印刷するだけなので、列をうまく整列しません。emacsとvimでこれを行う方法を知っていますが、配管などの標準出力に表示される出力

私が思いついた解決策は、sdiffを使用し、次にsedにパイプしてsdiffの出力を削除します。

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

関数を作成して_.bashrc_に貼り付けることはできますが、このコマンドは確かに既に存在します(またはcleanerソリューションである可能性があります)?

84
Chris Seymour

prを使用してこれを行うことができます。-mフラグ、ファイルをマージし、列ごとに1つ、-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

参照:

150
Hasturkun

@ Hasturkun の答えを少し拡張するには、デフォルトでprは出力に72列のみを使用しますが、ターミナルウィンドウで使用可能なすべての列を使用するのは比較的簡単です。

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

ほとんどのシェルは、端末の画面幅を$COLUMNS環境変数に(および更新)格納するため、その値をprに渡すだけです。出力の幅設定に使用します。

これは @ Matt の質問にも答えます:

Prが画面幅を自動検出する方法はありますか?

したがって、いいえ:pr自体は画面幅を検出できませんが、-wオプションを介して端末の幅を渡すことで少し助けています。

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

形式仕様で*を使用すると、フィールド長を動的に指定できます。

6
Barmar

入力ファイルにタブがないことがわかっている場合、expandを使用すると、 @ oyssanswer が簡素化されます。

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

入力ファイルにタブがある場合は、常に最初に展開できます。

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

barmarの答えから動的にフィールドの長さのカウントを削除すると、コマンドがはるかに短くなります。

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

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
2
user3498040

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最も正確な!です)

1
F. Hauri

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
0
funk
diff -y <file1> <file2>


[root /]# cat /one.txt
アップル
ナシ
最後の2つより長い行
最後の行
[root /]# cat /two.txt
クイックブラウンフォックス.. 
 foo 
 bar 
 linux 
[[email protected] /]# diff -y one.txt two.txt
アップル|速い茶色のキツネ.. 
ナシ| foo 
最後の2つより長い行| bar 
最終行| linux 
0
iAdhyan