110

長さの異なる 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でこれを行う方法は知っていますが、パイプなどのために出力をstdoutに表示したい.

私が思いついた解決策は、使用してsdiffからsedにパイプして出力を削除することsdiffです。

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

関数を作成して自分に貼り付けることはできますが、.bashrcこれに対するコマンドは既に存在します (または、よりクリーンなソリューションになる可能性があります)。

4

9 に答える 9

192

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

関連項目:

于 2012-11-12T12:44:51.757 に答える
36

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

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

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

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

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

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

于 2014-05-08T13:40:53.663 に答える
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])}
}'

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

于 2012-11-12T10:47:54.813 に答える
3

方法があり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 /;
    "

の下では、次を使用できますprintf -v

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

(もちろん、@Hasturkun のソリューションpr最も正確です!) :

sed以上のメリットpr

分離幅やセパレーターを細かく選択できます。

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

または、サンプルとして、以下を含む行をマークするにはline:

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

レンダリングします:

apple                         |  | The quick brown fox..
pear                          |  | foo
longer line than the last two |ln| bar 
last line                     |ln| linux
                              |  | 
                              |ln| skipped a line
于 2013-01-04T14:43:11.040 に答える
2

Barmarの回答から動的にフィールド長カウントを削除すると、コマンドがはるかに短くなります....しかし、どの方法を選択しても回避できなかった作業を完了するには、少なくとも1つのスクリプトが必要です。

paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$2)}'
于 2012-11-12T12:17:33.753 に答える
2

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
于 2015-01-12T10:12:55.153 に答える
1

以下の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
于 2016-01-29T15:01:00.493 に答える
0
diff -y <file1> <file2>


[root /]# cat /one.txt
りんご
梨
最後の 2 つより長い列
最後の行
[root /]# cat /two.txt
速い茶色のキツネ..
ふー
バー
Linux
[root@RHEL6-64 /]# diff -y one.txt two.txt
リンゴ | 速い茶色のキツネ..
梨 | ふー
最後の 2 つより長い行 | バー
最後の行 | Linux
于 2014-01-01T11:49:18.667 に答える