ortak çizgiler nasıl gösterilir (ters fark)?


170

Aralarında farklı olan satırlar yerine ortak satırları bilmek istediğim bir dizi metin dosyası var. Komut satırı unix veya windows gayet iyi.

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)

bar:

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

Bu nedenle, istenen iki yardımcı programın çıktısının üzerindeki bu iki dosya göz önüne alındığında file1:line_number, file2:line_number == matching text (sadece bir öneri, sözdiziminin ne olduğunu umursamıyorum):

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

Teşekkürler.


@ChristopherSchultz Benim hatam. 1. örnekteki 1. satır, 2. örnekteki son satırla eşleşiyordu. Hatayı yakaladığınız için teşekkür ederiz; değiştirme.
matt wilkie

1
İyi cevapları olan başka bir benzer soru: unix.stackexchange.com/questions/1079/…
MortezaE

Yanıtlar:


210

* Nix üzerinde comm . Sorunun cevabı:

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

İşte tam kullanımı 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. 

Ayrıca, man sayfalarında belirtildiği gibi, comm kullanmadan önce dosyaları sıralamanın önemli olduğunu unutmayın.


3
comm [-1] [-2] [-3] dosya1 dosya2 -1 Dosya1'e özgü satırların çıktı sütununu bastır. -2 Dosya2'ye özgü satırların çıkış sütununu bastırın. -3 dosya1 ve dosya2'de yinelenen satırların çıkış sütununu bastırın.
ojblass

@ojblass: Bunu yanıta ekledi.
Matt J

6
Comm kullanmadan önce dosyaların sıralanmasının önemli olduğunu keşfettim. Belki de cevaba ekleyin.
matt wilkie

11
soruya kısa cevap: comm -1 -2 file1 file2
greggles

6
Dosyalarınız sıralanmamışsa bunu kullanabilirsiniz: comm -1 -2 <(sort filename1) <(sort filename2)
Kevin Wheeler

56

Bu yanıtı, kopya olarak listelenen bir soruda buldu . Grep'in comm'den daha yönetici dostu olduğunu düşünüyorum, bu yüzden sadece eşleşen satırlar kümesi istiyorsanız (örneğin, CSV'leri karşılaştırmak için yararlıdır)

grep -F -x -f file1 file2

veya basitleştirilmiş fgrep sürümü

fgrep -xf file1 file2

Ayrıca, file2*iki yerine birden fazla dosyayla ortak satırları bulmak ve aramak için kullanabilirsiniz .

Diğer bazı kullanışlı varyasyonlar

  • -n eşleşen her satırın satır numarasını gösteren bayrak
  • -c yalnızca eşleşen satır sayısını saymak için
  • -vyalnızca dosya2'de farklı olan (veya kullanılan diff) satırları görüntülemek için .

Kullanmak commdaha hızlıdır, ancak bu hız önce dosyalarınızı sıralamak zorunda kalacaktır. 'Ters fark' olarak çok kullanışlı değil.


teşekkürler Ryder, bu birçok kişiye daha yararlı olabilir. Kaynak cevaba bağlantı vermelisiniz (sağdaki nav'da Q'da yarım düzineden fazla bağlantı var; bulmak biraz iş). Ayrıca grep'in un- veya farklı olarak sıralanmış girdilerle ne kadar iyi olduğunu bilmek de iyi olur ve ilgili satır numaralarını eşleşmeler yazdırabilir.
matt wilkie

1
@mattwilkie Geri gelip -vbayrağın kullanımını kendim bıraktıktan sonra açıklığa kavuşturmam gerektiğini hissettim . Dosya1 ve dosya2 olmak üzere iki csv dosyanız olduğunu ve bunların hem çakışan hem de çakışmayan satırları olduğunu varsayalım. Yalnızca üst üste binmeyen satırların tümünü ve isterseniz fgrep -v file1 file2, yalnızca dosya2'deki çakışmayan satırları döndürür ve dosya1'deki ek çakışmayan satırların hiçbirini döndürmez . Bu bazıları için aşikar olabilir, ancak bariz olanı yanlış yorumlamaktan daha iyi ifade etmek daha iyidir. Bu özel durumda, dosyaları sıralamak ve kullanmak commhala daha iyi bir seçimdir.
Ryder

1
Geri döndüğünüz ve Ryder'ı açıkladığınız için teşekkür ederiz. Ekstra dikkat not edilir ve takdir edilir (tüm t0o eski şeylerin kaymasına izin vermek kolaydır!). Kabul edilen cevabı değiştirdim çünkü iletişim, sıralamada istenmeyen ek yük olduğunda hala kişisel olarak kullanmama rağmen, açıkça toplumun tercihi.
matt wilkie

2
Kullanırken ortaya çıkan bir diğer sorun grep: ilk dosyadaki boş satırlar ikinci dosyadaki her satırla eşleşir. file1Boş satır olmadığından emin olun , aksi takdirde dosyalar aynı görünür.
Christopher Schultz

grep -Fxfbenim için.
loxaxs

35

Burada daha önce sorulmuştu: İki dosyada ortak olan hatları bulmak için Unix komutu

Perl ile de deneyebilirsiniz (kredi buraya gelir )

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

1
Teşekkürler. Perl bir astar çapraz platform olduğu için her iki yanıtı da kabul etmek isterim. Comm daha basit olduğu için başını sallar.
matt wilkie

1
Mükemmel. Cygwin terminalini pencerelerde kullanmak ve commmevcut değildi. Bu mükemmel bir alternatifti.
Qix - MONICA

3
Bu, hatların nasıl sipariş edildiğini umursamıyor. İletişimden daha doğru.
enl8enmentnow


17

Bu komuttan comm komutunu yeni öğrendim, ancak ekstra bir şey eklemek istedim: dosyalar sıralanmamışsa ve orijinal dosyalara dokunmak istemiyorsanız, sıralama komutunun çıkışını kullanabilirsiniz. Bu, orijinal dosyaları olduğu gibi bırakır. Bash'da çalışır, diğer mermiler hakkında söyleyemem.

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

Bu, dosyalar yerine komut çıktısını karşılaştırmak için genişletilebilir:

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

9

En kolay yol:

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

Dosyaların sıralanması gerekmez.


1
Bu, kaynak şablonlarını yeniden yapılandırmanıza izin verdiği için, buradaki cevapların çoğundan farklıdır. Birkaç noktaya farklı metin eklenmiş, aynı sarmalayıcı inşa iki dosya var. Bu cevap sarmalayıcıyı kurtarmamı sağladı.
Lucas Gonze

1

Sadece bilgi için, Windows için "grep -F -x -f file1 file2" dosyasından aynı şeyi yapan küçük bir araç yaptım (Windows'ta bu komuta eşdeğer bir şey bulamadım)

İşte: http://www.nerdzcore.com/?page=commonlines

Kullanım "CommonLines inputFile1 inputFile2 outputFile" şeklindedir.

Kaynak kodu da mevcuttur (GPL)


1

In Windows'un bir kullanabilirsiniz PowerShell ile Komut CompareObject

compare-object -IncludeEqual -ExcludeDifferent -PassThru (get-content A.txt) (get-content B.txt)> MATCHING.txt | Out-Null #Find Matching Lines

CompareObject:

  • -ExcludeDifferent olmadan IncludeEqual: Her şey
  • -InclueEqual içermeyen farklı: Hiçbir şey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.