2012-05-07 29 views
8

Tôi có hai tệp A và B. Tôi muốn tìm tất cả các dòng trong A không có trong B. Cách nhanh nhất để làm điều này trong bash/sử dụng các tiện ích Linux tiêu chuẩn là gì? Dưới đây là những gì tôi đã thử cho đến thời điểm này:Làm thế nào để tìm thấy sự khác biệt thiết lập của hai tập tin?

for line in `cat file1` 
do 
    if [ `grep -c "^$line$" file2` -eq 0]; then 
    echo $line 
    fi 
done 

Nó hoạt động nhưng chậm. Có cách nào nhanh hơn để làm việc này không?

+0

Bạn có thể hiển thị một số mã hoặc giải thích những gì bạn đã thử không? Câu hỏi của bạn như nó đứng làm cho nó có vẻ như bạn muốn chúng tôi làm tất cả công việc cho bạn. Thông thường, việc hiển thị mã sẽ giúp khuyến khích nhiều câu trả lời hơn và kết quả tốt hơn. – jmort253

+0

Bạn cũng nên xác định những gì bạn mong đợi bằng "nhanh nhất". Đó là về thời gian xử lý hoặc thời gian viết mã. Đối với thứ hai, tôi sẽ đi cho một cái gì đó như 'diff A B | grep '^ -' ' – tonio

+0

@ jmort253, cảm ơn, tôi đã chỉnh sửa câu hỏi để thêm chi tiết – spinlok

Trả lời

20

describes doing exactly this with comm, là phương pháp chính xác theo đúng chuẩn.

# Subtraction of file1 from file2 
# (i.e., only the lines unique to file2) 
comm -13 <(sort file1) <(sort file2) 

diff ít phù hợp hơn cho tác vụ này vì nó cố gắng hoạt động trên các khối thay vì các dòng riêng lẻ; như vậy, các thuật toán mà nó phải sử dụng phức tạp hơn và ít hiệu quả về bộ nhớ hơn.

comm là part of the Single Unix Specification kể từ SUS2 (1997).

+0

Đây chính xác là những gì tôi đang tìm kiếm! Cảm ơn! – spinlok

+0

Đó là một chương trình tiện dụng. Tôi chưa từng thấy cái đó trước đây. Tôi tự hỏi những gì đá quý nhỏ của các ứng dụng vỏ mà quá khứ của tôi là một sysadmin bỏ qua. –

1

Chương trình 'khác' là chương trình Unix chuẩn, xem xét sự khác biệt giữa các tệp.

% cat A 
a 
b 
c 
d 
% cat B 
a 
b 
e 
% diff A B 
3,4c3 
< c 
< d 
--- 
> e 

Với một grep đơn giản và cắt có thể chọn các dòng trong A, không phải trong B. Lưu ý rằng cắt khá đơn giản và không gian trong dòng sẽ vứt đi ... nhưng khái niệm ở đó.

% diff A B | grep '^<' | cut -f2 -d" " 
c 
d 
2

Nếu bạn chỉ muốn dòng có trong tập tin A, nhưng không phải trong B, bạn có thể sắp xếp các tập tin, và so sánh chúng với diff.

sort A > A.sorted 
sort B > B.sorted 
diff -u A.sorted B.sorted | grep '^-' 
+4

Bạn không cần tệp tạm thời cho điều đó. 'diff <(sắp xếp A) <(sắp xếp B) | grep '^ -' ' – jordanm

+0

Vâng, nó thậm chí còn rõ ràng hơn theo cách này, nhờ – tonio

Các vấn đề liên quan