유닉스에서 두 개의 다른 파일을 한 줄씩 비교하는 방법은 무엇입니까?


13

파일 1 :

123
234
345
456

파일 2 :

123
234
343
758

예상 출력 : File3 :

TRUE
TRUE
FALSE
FALSE

따라서 코드는 두 파일을 비교하고 일치하는 경우 'TRUE'를 인쇄하고 그렇지 않으면 새 파일에서 'FALSE'를 인쇄해야합니다. 누구든지 이것에 대한 해결책을 제공 할 수 있습니까?


10
두 파일의 길이가 다른 경우 어떻게됩니까? 이 문제의 해결 방법 중 어떤 부분에 문제가 있습니까?
Kusalananda

9
을 살펴볼 수도 있습니다 diff.
Panki

2
이러한 상황에서 다른 유용한 명령은 comm입니다. 두 파일이 공통이거나 고유 한 행을 쉽게 나열 할 수 있습니다.
Giacomo Alzetta

1
@GiacomoAlzetta와 함께하는 것은 comm정렬 된 입력이 필요하다는 것입니다 . 질문의 예가 입력을 정렬 했다는 사실 외에도, 질문 이것이 사용되는 실제 데이터라고 주장하지 않으며 데이터 순서에 대해 아무 것도 말하지 않습니다.
Kusalananda

2
αғsнιη의 nl트릭은 comm파일에 정렬 성을 부여하는 데 유용 합니다.
glenn jackman

답변:


56

사용 diff에서, 다음과 같은 명령을 bash지원하는 것을 나 다른 쉘 <(...) 대체를 처리 하거나 다음과 같이 당신이 그것을 에뮬레이션 할 수 있습니다 :

diff --new-line-format='FALSE'$'\n' \
     --old-line-format='' \
     --unchanged-line-format='TRUE'$'\n' \
<(nl file1) <(nl file2)

결과는 다음과 같습니다.

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\n, FALSE줄이 다르면 인쇄 --old-line-format=''하고 이전 파일을 diff 명령 으로 알려진 file1에 대해 줄이 다를 경우 출력을 비활성화합니다 (이를 서로 바꿀 수 있으므로 둘 중 하나는 FALSE다른 것을 인쇄해야 함을 의미 합니다).

--unchanged-line-format='TRUE'$'\n'TRUE줄이 같은 경우 인쇄 하십시오. $'\n'C 스타일 이스케이프 구문은 각각의 라인 출력 후 새로운 라인을 인쇄하는데 사용된다.


24

파일에 탭 문자가 없다고 가정합니다.

$ paste file1 file2 | awk -F '\t' '{ print ($1 == $2 ? "TRUE" : "FALSE") }'
TRUE
TRUE
FALSE
FALSE

이는 paste두 파일의 내용이 어느 한 열에있는 두 개의 탭으로 구분 된 열을 만드는 데 사용 됩니다. 이 awk명령은 각 줄의 두 열을 비교하여 TRUE열이 같으면 인쇄하고 그렇지 않으면 인쇄합니다 FALSE.


10

두 파일의 행 수가 같다고 가정합니다.

awk '{getline f2 < "file2"; print f2 == $0 ? "TRUE" : "FALSE"}' file1

비교 할 문자열이 숫자이고 어휘가 아닌 경우 숫자 비교를 수행합니다. 예를 들어, 100과는 1.0e2동일 간주됩니다. f2"" == $0어쨌든 어휘 비교를 강제로 변경하십시오 .

awk구현 에 따라 어휘 비교는 memcmp()(바이트 대 바이트 비교)를 사용하는 것처럼 또는 strcoll()두 문자열이 로케일의 데이터 정렬 순서에서 동일하게 정렬되는지 를 사용하는 것처럼 수행됩니다 . 샘플과 같이 모든 10 진수 입력이 아니라 일부 문자에 대해 순서가 올바르게 정의되지 않은 로케일에서 차이가 생길 수 있습니다.


7

파이썬 3

with open('file1') as file1, open('file2') as file2:
    for line1, line2 in zip(file1, file2):
        print(line1 == line2)

산출:

True
True
False
False

당신이 필요로하는 경우 TRUEFALSE대문자로,이 중 하나를 사용하여 인쇄 라인을 교체 :

print(str(line1 == line2).upper())
print('TRUE' if line1 == line2 else 'FALSE')

2
Python 2에서는 import itertools먼저 수행 한 다음 itertools.izip대신 사용하십시오 zip. 그렇지 않으면 두 파일을 모두 메모리로 읽고 너무 많은 메모리를 사용합니다.
pts

4

에서 bash, while루프 에서 각 파일을 읽고, 읽기 행을 비교하고 인쇄 TRUE하거나 FALSE적절하게 :

while IFS= read -r -u3 line1; IFS= read -r -u4 line2; do
    [[ $line1 == $line2 ]] && echo TRUE || echo FALSE
done 3<file1 4<file2

read파일 디스크립터 3과 4에서 각각 두 번의 호출을 읽습니다. 파일은 루프로의 두 가지 입력 경로 재 지정을 통해 파일로 경로 재 지정됩니다.


0
Tried with awk command and it worked fine


awk 'NR==FNR{a[$1];next}{if ($1 in a){print "TRUE"} else{print "False"}}' file1 file2

산출

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