Xuất ra các dòng chung (tương đồng) của hai tệp văn bản (ngược lại với diff)?


20

Diff là một công cụ tuyệt vời để hiển thị các thay đổi giữa hai tệp. Nhưng làm thế nào để hiển thị sự tương đồng của hai tệp văn bản (trong khi bỏ qua sự khác biệt)?

Tức là đầu vào mẫu:

a:
Foo Bar
X
Hello
World
42

b:
Foo Baz
Hello
World
23

Đầu ra giả (một cái gì đó như thế này):

@@ 2,3
=Hello World

Chỉ cần sắp xếp cả hai tệp và sử dụng comm là không đủ, vì trong trường hợp đó, thông tin dòng bị mất.

Câu trả lời:


24

Làm thế nào về việc sử dụng diff, mặc dù bạn không muốn một diff? Thử đi:

diff --unchanged-group-format='@@ %dn,%df 
  %<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt

Đây là những gì tôi nhận được với dữ liệu mẫu của bạn:

$ cat a.txt 
Foo Bar
X
Hello
World
42
$ cat b.txt 
Foo Baz
Hello
World
23
$ diff --unchanged-group-format='@@ %dn,%df
%<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt
@@ 2,3
Hello
World

2
Bạn có thể tránh nhúng một dòng mới theo nghĩa đen như sau:...%df'$'\n''%<'...
Tạm dừng cho đến khi có thông báo mới.

1
Bạn cũng có thể làm như thế này: ... --unchanged-group-format="@@ %dn,%df%c'\012'%<" ...(Lưu ý dấu ngoặc kép.)
Tạm dừng cho đến khi có thông báo mới.

Công cụ tuyệt vời! Tôi không biết các tùy chọn này, vì tôi chỉ nhìn vào trang diff man ...
maxschlepzig

Tôi đang sử dụng diff --version diff (GNU diffutils) 2.8.1 Và tôi gặp lỗi sau: diff: xung đột tùy chọn kiểu đầu ra diff: Hãy thử `diff --help 'để biết thêm thông tin.
Sujay

Tôi đã nhận được "error: diff: xung đột tùy chọn kiểu đầu ra diff" bởi vì tôi có một bí danh khác được định nghĩa. Sử dụng which diffđể xem nếu đây là vấn đề của bạn.
justinjhendrick

14
grep -Fxf file1 file2

-Fcó nghĩa là khớp chuỗi đơn giản (không phải biểu thức chính quy), -xnghĩa là chỉ khớp toàn dòng, -fnghĩa là lấy 'mẫu' (nghĩa là các dòng) từ tệp có tên làm đối số của nó


3
Không -f-Ftrao đổi?. Ít nhất trong grepphiên bản của tôi là như thế. Tôi cần cung cấp file2đầu vào cho -fđối số, như cat file1 | grep -Fxf file2, và sau đó hoạt động.
Birei

Điều này không làm việc cho tôi.
Chaminda Bandara

7

Tôi không nghĩ có một lệnh duy nhất thực hiện những gì bạn muốn nó làm. Bạn có thể thử kết hợp đầu ra diffvới grep. Nếu tập tin văn bản của bạn chứa không ai trong số các nhân vật |, <, >, sau đây cung cấp cho bạn lượng hơi hữu ích:

$ diff --side-by-side a b | grep -n -v "[|<>]"
3:Hello                             Hello
4:World                             World

Hãy thử điều này:diff --width=155 --left-column --side-by-side a b | grep -n -v '|' | sed 's/ *($//'
Tạm dừng cho đến khi có thông báo mới.

có vẻ tốt hơn - nhưng bạn phải bao gồm <và> trong grep để loại bỏ các dòng được thêm vào trong một trong hai tệp.
Marcel Promotionberg

6

commcó thể được sử dụng. man commcho tất cả các tùy chọn nhưng bạn sẽ muốn sử dụng comm -12 ...để chỉ hiển thị các dòng tồn tại trong cả hai đầu vào.

Như mọi người đã chỉ ra, trước tiên bạn cần chuyển đầu vào của mình sort.


1
Hừm, chỉ hoạt động đối với các dòng chung có cùng số dòng trong cả hai tệp.
maxschlepzig

2
comm dường như chỉ dành cho các tệp được sắp xếp và không cung cấp đầu ra hữu ích đó cho usecase của OP. Ví dụ của anh ấy: $ comm -12 ab Hello World comm: tập tin 1 không theo thứ tự comm: tập tin 2 không theo thứ tự được sắp xếp
Marcel Promotionberg

@maxschlepzig: bạn nên sắp xếp các tệp của mình trước khi chuyển chúng sang comm.
Hemant

2
Tuy nhiên, bằng cách sắp xếp, bạn thoát khỏi tất cả các thông tin về vị trí của các dòng chung. Bạn sẽ không sắp xếp các tập tin trước khi so sánh chúng với diff.
Marcel Promotionberg

2

Dick Grune đã viết một gia đình các công cụ cho loại điều này:

http://dickgrune.com/Programs/similarity_tester/

Có những phiên bản phân tích cú pháp của các ngôn ngữ khác nhau, để những thứ như biến đổi tên có thể được xem là không thay đổi.

Nó được đóng gói như similarity-testertrong Debian và Ubuntu.

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.