Keluarkan baris umum (kesamaan) dari dua file teks (kebalikan dari diff)?

21

Diff adalah alat yang hebat untuk menampilkan perubahan antara dua file. Tetapi bagaimana cara menampilkan kesamaan dari dua file teks (sambil mengabaikan perbedaannya)?

Yaitu input sampel:

a:
Foo Bar
X
Hello
World
42

b:
Foo Baz
Hello
World
23

Output semu (sesuatu seperti ini):

@@ 2,3
=Hello World

Menyortir kedua file dan menggunakan comm tidak cukup, karena dalam kasus itu informasi baris hilang.

maxschlepzig
sumber

Jawaban:

24

Bagaimana dengan menggunakan diff, meskipun Anda tidak ingin diff? Coba ini:

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

Inilah yang saya dapatkan dengan data sampel Anda:

$ 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
Mike Gray
sumber
2
Anda dapat menghindari menyematkan baris baru literal seperti ini:...%df'$'\n''%<'...
Dijeda sampai pemberitahuan lebih lanjut.
1
Anda juga dapat melakukannya seperti ini: ... --unchanged-group-format="@@ %dn,%df%c'\012'%<" ...(Perhatikan tanda kutip ganda.)
Dijeda sampai pemberitahuan lebih lanjut.
Barang bagus! Saya tidak tahu opsi ini, karena saya hanya melihat halaman manual diff ...
maxschlepzig
Saya menggunakan diff --version diff (GNU diffutils) 2.8.1 Dan saya mendapatkan kesalahan berikut: diff: opsi gaya keluaran yang bertentangan diff: Coba `diff --help 'untuk informasi lebih lanjut.
Sujay
Saya mendapatkan "error: diff: opsi gaya keluaran yang bertentangan" karena saya memiliki alias yang terdefinisi. Gunakan which diffuntuk melihat apakah ini masalah Anda.
justinjhendrick
14
grep -Fxf file1 file2

-Fberarti mencocokkan string biasa (bukan regexps), -xberarti hanya pencocokan seluruh baris, -fberarti mengambil 'pola' (yaitu baris) dari file yang dinamai argumennya

tobyodavies
sumber
3
Bukankah -fdan -Fdipertukarkan? Setidaknya dalam grepversi saya seperti itu. Saya perlu memberikan file2masukan untuk -fargumen, seperti cat file1 | grep -Fxf file2, dan kemudian berfungsi.
Birei
Ini tidak berhasil untuk saya.
Chaminda Bandara
7

commdapat digunakan. man communtuk semua opsi tetapi Anda ingin menggunakannya comm -12 ...untuk hanya menampilkan garis yang ada di kedua input.

Seperti yang telah ditunjukkan orang, Anda harus mengirimkan masukan sortterlebih dahulu.

Oli
sumber
1
Hm, itu hanya berfungsi untuk baris umum yang berada di nomor baris yang sama di kedua file.
maxschlepzig
2
comm tampaknya hanya untuk file yang diurutkan dan bukan untuk memberikan output yang bermanfaat untuk usecase OP. Contohnya: $ comm -12 ab Hello World comm: file 1 tidak berurutan comm: file 2 tidak berurutan
Marcel Stimberg
@maxschlepzig: Anda harus mengurutkan file Anda sebelum meneruskannya ke comm.
Hemant
2
Dengan menyortir Anda menyingkirkan semua informasi tentang posisi garis yang sama. Anda juga tidak akan mengurutkan file sebelum membandingkannya dengan diff.
Marcel Stimberg
7

Saya tidak berpikir ada satu perintah yang melakukan apa yang Anda inginkan. Anda dapat mencoba menggabungkan output diffdengan grep. Jika file teks Anda tidak ada karakter mengandung |, <, >, berikut ini memberikan output yang agak berguna:

$ diff --side-by-side a b | grep -n -v "[|<>]"
3:Hello                             Hello
4:World                             World
Marcel Stimberg
sumber
Coba ini:diff --width=155 --left-column --side-by-side a b | grep -n -v '|' | sed 's/ *($//'
Dijeda sampai pemberitahuan lebih lanjut.
yang terlihat lebih baik - tetapi Anda harus memasukkan <dan> dalam grep untuk juga menyingkirkan baris yang ditambahkan di kedua file.
Marcel Stimberg
2

Dick Grune menulis sekumpulan alat untuk hal semacam ini:

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

Ada versi yang menguraikan sintaks berbagai bahasa, sehingga hal-hal seperti variabel yang diubah namanya dapat dilihat sebagai tidak berubah.

Dikemas seperti similarity-testerdi Debian dan Ubuntu.

Douglas Bagnall
sumber