Làm thế nào để so sánh hai tập tin khác nhau theo từng dòng trong unix?


13

Tệp1:

123
234
345
456

Tệp2:

123
234
343
758

Đầu ra dự kiến: File3:

TRUE
TRUE
FALSE
FALSE

vì vậy mã phải so sánh hai tệp và in 'TRUE' nếu nó khớp với nếu không nó sẽ in 'FALSE' trong tệp mới. Bất cứ ai có thể xin vui lòng cung cấp giải pháp cho điều này?


10
Điều gì xảy ra nếu hai tệp có độ dài không bằng nhau? Phần nào của giải pháp cho vấn đề này là bạn đang gặp vấn đề?
Kusalananda

9
Bạn có thể muốn xem qua diff.
Panki

2
Lệnh hữu ích khác trong những tình huống này là comm. Nó giúp dễ dàng liệt kê các dòng mà cả hai tệp có điểm chung hoặc là duy nhất cho cái này hoặc cái kia.
Giacomo Alzetta

1
@GiacomoAlzetta Điều cần làm commlà nó yêu cầu đầu vào được sắp xếp. Ngoài thực tế là các ví dụ trong câu hỏi không có đầu vào sắp xếp, câu hỏi không bao giờ khẳng định rằng đây là dữ liệu thực tế đang được sử dụng và không bao giờ nói bất cứ điều gì về trật tự của dữ liệu.
Kusalananda

2
Thủ nlthuật của αsнιη rất hữu ích với commviệc áp đặt tính chất được sắp xếp trên các tệp.
glenn jackman

Câu trả lời:


56

Sử dụng difflệnh như sau, trong bashhoặc bất kỳ shell nào khác hỗ trợ <(...) thay thế quá trình hoặc bạn có thể mô phỏng nó như hiển thị ở đây :

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

Đầu ra sẽ là:

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\n, in FALSEnếu các dòng khác nhau và với --old-line-format=''chúng tôi vô hiệu hóa đầu ra nếu dòng khác với tệp 1, được gọi là tệp thành lệnh diff (Chúng tôi cũng có thể trao đổi các dòng này, nghĩa là một trong số chúng nên in FALSEmột dòng khác nên bị vô hiệu hóa.)

--unchanged-line-format='TRUE'$'\n', in TRUEnếu các dòng giống nhau. các $'\n'cú pháp thoát C-phong cách được sử dụng để in một dòng mới sau mỗi lần ra đường.


24

Giả sử các tệp không chứa ký tự tab:

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

Điều này sử dụng pasteđể tạo hai cột được phân định bằng tab, với nội dung của hai tệp trong một trong hai cột. Các awklệnh so sánh hai cột trên mỗi dòng và in TRUEnếu các cột đều giống nhau và nếu không in FALSE.


10

Giả sử cả hai tệp có cùng số dòng:

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

Đó là thực hiện so sánh bằng số nếu các chuỗi để so sánh là số và từ vựng khác. Ví dụ, 1001.0e2sẽ được coi là giống hệt nhau. Thay đổi thànhf2"" == $0 buộc một so sánh từ vựng trong mọi trường hợp.

Tùy thuộc vào việc awktriển khai, so sánh từ vựng sẽ được thực hiện như thể bằng cách sử dụng memcmp()(so sánh byte với byte) hoặc bằng cách sử dụng strcoll()(cho dù hai chuỗi sắp xếp giống nhau theo thứ tự đối chiếu của miền địa phương). Điều đó có thể tạo ra sự khác biệt ở một số địa phương nơi thứ tự không được xác định đúng cho một số ký tự, không phải trên tất cả đầu vào chữ số thập phân như trong mẫu của bạn.


7

Con trăn 3

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

Đầu ra:

True
True
False
False

Nếu bạn cần TRUEFALSEviết hoa, thay thế dòng in bằng một trong những điều sau:

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

2
Trong Python 2, hãy thực hiện import itertoolstrước, sau đó sử dụng itertools.izipthay vì zip. Nếu không, nó sẽ đọc cả hai tập tin vào bộ nhớ, có thể sử dụng quá nhiều bộ nhớ.
pts

4

Trong bash, đọc từ mỗi tệp trong một whilevòng lặp, so sánh các dòng đọc và in TRUEhoặc FALSEmột cách thích hợp:

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

Hai cuộc gọi để readđọc từ mô tả tập tin 3 và 4 tương ứng. Các tập tin được chuyển hướng đến những cái này với hai lần chuyển hướng đầu vào vào vòng lặp.


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

đầu ra

TRUE
TRUE
False
False
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.