2009-04-14 24 views
137

Tôi có một loạt tệp văn bản mà tôi muốn biết các dòng chung hơn là các dòng khác nhau giữa chúng. Unix dòng lệnh hoặc cửa sổ là tốt.làm thế nào để hiển thị dòng chung (đảo ngược khác nhau)?

foo:

linux-vdso.so.1 => (0x00007fffccffe000) 
libvlc.so.2 => /usr/lib/libvlc.so.2 (0x00007f0dc4b0b000) 
libvlccore.so.0 => /usr/lib/libvlccore.so.0 (0x00007f0dc483f000) 
libc.so.6 => /lib/libc.so.6 (0x00007f0dc44cd000) 

thanh:

libkdeui.so.5 => /usr/lib/libkdeui.so.5 (0x00007f716ae22000) 
libkio.so.5 => /usr/lib/libkio.so.5 (0x00007f716a96d000) 
linux-vdso.so.1 => (0x00007fffccffe000) 

Vì vậy, với hai tập tin trên đầu ra của các tiện ích mong muốn sẽ giống như file1:line_number, file2:line_number == matching text (chỉ cần một gợi ý, tôi thực sự không quan tâm cú pháp là gì):

foo:1, bar:3 == linux-vdso.so.1 => (0x00007fffccffe000) 

thanks.

+0

@ChristopherSchultz Sai lầm của tôi. Dòng đầu tiên trong ví dụ thứ nhất được cho là phù hợp với dòng cuối cùng trong ví dụ thứ 2. Cảm ơn bạn đã bắt gặp lỗi; thay đổi. –

+1

Một câu hỏi tương tự khác có câu trả lời hay: http://unix.stackexchange.com/questions/1079/output-the-common-lines-similarities-of-two-text-files-the-opposite-of-diff – MortezaE

Trả lời

169

Trên * nix, bạn có thể sử dụng comm. Câu trả lời cho câu hỏi là:

comm -1 -2 file1.sorted file2.sorted 
# where file1 and file2 are sorted and piped into *.sorted 

Dưới đây là cách sử dụng đầy đủ các comm:

comm [-1] [-2] [-3 ] file1 file2 
-1 Suppress the output column of lines unique to file1. 
-2 Suppress the output column of lines unique to file2. 
-3 Suppress the output column of lines duplicated in file1 and file2. 

Cũng lưu ý rằng điều quan trọng là để sắp xếp các file trước khi sử dụng comm, như đã đề cập trong các trang người đàn ông.

+1

comm [ -1] [-2] [-3] file1 file2 -1 Ngăn chặn cột đầu ra của các dòng duy nhất thành tệp1. -2 Loại bỏ cột đầu ra của các dòng duy nhất thành tệp2. -3 Ngăn chặn cột đầu ra của các dòng được sao chép trong tệp1 và tệp2. – ojblass

+0

@ojblass: Đã thêm câu trả lời này vào câu trả lời. –

+3

Tôi phát hiện ra rằng điều quan trọng là các tập tin được sắp xếp trước khi sử dụng comm. Có lẽ thêm vào câu trả lời. –

32

Được hỏi ở đây trước: Unix command to find lines common in two files

Bạn cũng có thể thử với perl (tín dụng goes here)

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' file1 file2 
+1

cảm ơn. Tôi đã muốn chấp nhận cả hai câu trả lời, như lớp lót perl là nền tảng chéo. Comm được gật đầu vì nó đơn giản hơn. –

+0

không có gì sai với giải pháp thay thế :) – Chris

+0

Hoàn hảo. Sử dụng thiết bị đầu cuối Cygwin trên các cửa sổ và 'dấu phẩy 'không có sẵn. Đây là giải pháp thay thế hoàn hảo. – Qix

11

Tôi chỉ học được lệnh comm từ chủ đề này, nhưng muốn thêm một cái gì đó thêm: nếu các tập tin không được sắp xếp, và bạn không muốn chạm vào các tập tin gốc, bạn có thể ống dẫn đầu của lệnh sắp xếp. Điều này để lại các tập tin gốc nguyên vẹn. Làm việc trong bash, tôi không thể nói về vỏ khác.

comm -1 -2 <(sort file1) <(sort file2) 

Điều này có thể được mở rộng để so sánh đầu ra lệnh, thay vì tập tin:

comm -1 -2 <(ls /dir1 | sort) <(ls /dir2 | sort) 
35

Tìm thấy câu trả lời này trên a question listed as a duplicate. Tôi thấy grep để có nhiều admin-thân thiện hơn comm, vì vậy nếu bạn chỉ muốn tập các dòng phù hợp (hữu dụng cho việc so sánh CSV, ví dụ) chỉ cần sử dụng

grep -F -x -f file1 file2 

hoặc fgrep đơn giản hóa phiên bản

fgrep -xf file1 file2 

Ngoài ra, bạn có thể sử dụng file2* để kết hợp và tìm kiếm các dòng chung với nhiều tệp chứ không phải chỉ hai tệp.

Một số biến thể có ích khác bao gồm

  • -n cờ để hiển thị số dòng của mỗi dòng phù hợp
  • -c chỉ đếm số lượng các dòng phù hợp với
  • -v để chỉ hiển thị các dòng trong file2 khác (hoặc sử dụng diff).

Sử dụng comm nhanh hơn, nhưng tốc độ đó đến với chi phí phải sắp xếp tệp của bạn trước. Nó không phải là rất hữu ích như là một 'đảo ngược khác'.

+0

cảm ơn Ryder, điều này có thể nhiều hơn hữu ích hơn so với nhiều. Bạn nên liên kết đến câu trả lời nguồn (có hơn nửa tá liên kết trong Q trong điều hướng bên phải; đó là một chút công việc cần tìm). Nó cũng sẽ được tốt đẹp để biết grep tốt như thế nào với đầu vào được phân loại chưa hoặc khác nhau, và có thể in số dòng tương ứng của trận đấu. –

+0

@mattwilkie - đã hoàn tất! – Ryder

+1

@mattwilkie Tôi cảm thấy cần phải quay lại và làm rõ việc sử dụng cờ '-v' sau khi tôi tự mình bỏ qua nó. Giả sử bạn có hai tệp csv tệp1 và tệp2 và chúng có cả hai hàng trùng lặp và không trùng nhau. Nếu bạn muốn tất cả và chỉ các hàng không chồng chéo, sử dụng 'fgrep -v file1 file2' sẽ chỉ trả về các hàng không chồng chéo trong tệp2, * và không có hàng nào chồng chéo bổ sung trong tệp1 *. Điều này có thể hiển nhiên đối với một số người, nhưng tốt hơn nên nêu rõ hơn là giải thích sai rủi ro. Trong trường hợp đặc biệt này, việc phân loại các tập tin và sử dụng 'dấu phẩy 'vẫn là lựa chọn tốt hơn. – Ryder

1

Chỉ cần cung cấp thông tin, tôi đã làm một công cụ nhỏ cho Windows làm điều tương tự hơn "grep -F -x -f file1 file2" (Như tôi đã không tìm thấy bất cứ điều gì tương đương với lệnh này trên Windows)

Ở đây là: http://www.nerdzcore.com/?page=commonlines

cách sử dụng "CommonLines inputFile1 inputFile2 outputFile"

Source code cũng có sẵn (GPL)

5

cách dễ nhất để làm là:

awk 'NR==FNR{a[$1]++;next} a[$1] ' file1 file2 

Không cần sắp xếp tệp.

+0

Điều này không giống như hầu hết các câu trả lời ở đây vì nó cho phép bạn xây dựng lại các mẫu nguồn. Tôi có hai tệp được tạo từ cùng một trình bao bọc, với văn bản khác được chèn vào một vài điểm. Câu trả lời này cho phép tôi khôi phục trình bao bọc. –

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