2011-12-15 28 views
12

Đôi khi tôi cần so sánh hai tệp văn bản. Rõ ràng, diff cho thấy sự khác biệt, nó cũng ẩn những điểm tương đồng, đó là loại điểm.* nix: thực hiện thiết lập union/intersection/sự khác biệt của danh sách

Giả sử tôi muốn thực hiện các so sánh khác trên các tệp này: đặt liên kết, giao cắt và trừ, xử lý từng dòng dưới dạng một phần tử trong tập hợp.

Có những tiện ích phổ biến đơn giản tương tự hoặc một lớp lót có thể thực hiện việc này không?


Ví dụ:

a.txt

john 
mary 

b.txt

adam 
john 

$> set_union a.txt b.txt 
john 
mary 
adam 

$> set_intersection a.txt b.txt 
john 

$> set_difference a.txt b.txt 
mary 
+0

Bạn có thể cho một ví dụ về những gì bạn có ý nghĩa bởi "công đoàn" ở đây? – fge

Trả lời

19

Union: sort -ufile ...

Intersection: sortfile ...| uniq -d

khác biệt: sortfile ...| uniq -u

7

Nếu bạn muốn để có được những dòng chung giữa hai tập tin, bạn có thể sử dụng tiện ích comm.

A.txt:

A 
B 
C 

B.txt

A 
B 
D 

và sau đó, sử dụng comm sẽ cung cấp cho bạn:

$ comm <(sort A.txt) <(sort B.txt) 
     A 
     B 
C 
    D 

Trong cột đầu tiên, bạn có những gì là trong tập tin đầu tiên và không phải trong lần thứ hai.

Trong cột thứ hai, bạn có nội dung trong tệp thứ hai và không có trong tệp thứ hai.

Trong cột thứ ba, bạn có nội dung trong cả hai tệp.

0

Nếu bạn không tâm trí sử dụng một chút Perl, và nếu kích thước tập tin của bạn là hợp lý để họ có thể được viết vào một băm, bạn có thể thu thập file thành hai băm để làm:

#...get common keys in an array... 
my @both_things 
for (keys %from_1) { 
    push @both_things, $_ if exists $from_2{$_}; 
} 

#...put unique things in an array... 
my @once_only 
for (keys %from_1) { 
    push @once_only, $_ unless exists $from_2($_); 
} 
0

Tôi không thể bình luận về câu trả lời Aaron Digulla, mà dù đã được chấp nhận không thực sự tính toán set difference.

Sự khác biệt được đặt A \ B với đầu vào đã cho chỉ được trả về mary, nhưng câu trả lời được chấp nhận cũng trả về không chính xác adam.

This answer có awk một liner tính một cách chính xác sự khác biệt thiết lập:

awk 'FNR==NR {a[$0]++; next} !a[$0]' b.txt a.txt 
Các vấn đề liên quan