두 파일을 나란히 표시


94

서로 다른 길이의 정렬되지 않은 텍스트 파일 2 개를 나란히 (열로) 표시 하는 방법shell

주어진 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있지만 확실히 이것에 대한 명령이 이미 존재 합니까 (또는 잠재적 으로 더 깨끗한 솔루션)?


쉘에서는 아니지만 언급 할 가치가 있습니다 : use meld !
fedorqui 'SO stop harming'9

답변:


166

당신은 사용할 수 있습니다 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

또한보십시오:


15
완전한! pr전에 들어 보지 못한 무언가가 존재할 것이라는 것을 알았습니다 . 3 개의 파일로 시도했는데 출력이 잘 렸지만 -w옵션으로 해결되었습니다. 좋은 대답입니다.
Chris Seymour 2011

5
@sudo_o : 행복 도움말을,로 coreutils는 보석이 가득
Hasturkun

1
pr이 화면 너비를 자동 감지하는 방법이 있습니까?
Matt

2
@Matt : $COLUMNS쉘에서 제공 해야하는를 사용할 수 있습니다 .
Hasturkun 2014-08-11

1
두 개의 파일을 나란히 인쇄 할 때 pr긴 줄 끝을 자릅니다. 줄을 감싸는 방법이 있습니까?
molnarg

32

@Hasturkun 의 대답 에 대해 조금 확장하려면 기본적 pr으로 출력에 72 열만 사용하지만 터미널 창에서 사용 가능한 모든 열을 사용하는 것은 비교적 쉽습니다.

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

대부분의 셸은 터미널의 화면 너비를 환경 변수에 저장 (및 업데이트)$COLUMNS 하므로 해당 값을에 전달 pr하여 출력 너비 설정에 사용합니다.

이것은 또한 @Matt 의 질문에 대답합니다.

pr이 화면 너비를 자동 감지하는 방법이 있습니까?

따라서 아니요 : pr자체적으로 화면 너비를 감지 할 수는 없지만 -w옵션을 통해 터미널 너비를 전달하여 약간의 도움을주고 있습니다.


7

입력 파일에 탭이 없다는 것을 알고 있다면을 사용 expand하면 @oyss대답이 단순화 됩니다 .

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

입력 파일에 탭이있는 경우 항상 먼저 확장 할 수 있습니다.

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

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

사용 *형식 스펙으로하면 동적 필드 길이를 제공 할 수 있습니다.


1
결코 그렇게 말하지 않았지만 가끔 두 개의 파일을 나란히 표시하고 싶다면 스크립트 를 작성 / 기억하는 것과 비교하여 표시되는 diff 추가 문자를 제거하는 diff -y one.txt two.txt것보다 더 나은 작업 을 수행 합니다. 둘 다 기능으로 더 오래! = 더 좋고, 더 읽기 쉽고, 더 빨리 .. 여기서 장점은 무엇입니까? paste one.txt two.txtsedawk.bash_rc
Chris Seymour 2011

2

Barmar의 대답에서 동적으로 필드 길이 계산을 제거하면 명령이 훨씬 더 짧아 지지만 어떤 방법을 선택하더라도 피할 수없는 작업을 완료하려면 여전히 하나 이상의 스크립트가 필요합니다.

paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$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

2

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

1

아래에서 파이썬 기반 솔루션을 찾으십시오.

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


[root /]# cat /one.txt
사과
배
마지막 두 줄보다 긴 줄
마지막 줄
[root /]# cat /two.txt
빠른 갈색 여우 ..
foo
바
리눅스
[root@RHEL6-64 /]# diff -y one.txt two.txt
사과 | 빠른 갈색 여우 ..
배 | foo
마지막 두 개보다 긴 줄 | 바
마지막 줄 | 리눅스

sdiff이다 diff -y내가 질문에 대해 논의한다.
Chris Seymour

네 맞습니다 ... 다른 명령 / 플래그 설정을 보여주기 위해 언급되었습니다.
iAdhyan 2014 년

그러나 그것은 diff두 파일 사이에 문자를 추가 하는 질문에 대답하지 않습니다 .
Chris Seymour

루트로이 작업을 수행하는 것이
두렵습니다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.