Yalnızca eklenmiş ve silinmiş satırları göstermek için nasıl farklılaşabilirim? Eğer diff bunu yapamazsa, hangi araç olabilir?


69

Yalnızca eklenmiş ve silinmiş satırları göstermek için nasıl farklılaşabilirim? Eğer diff bunu yapamazsa, hangi araç olabilir?


2
Ne demek istediğinizi ekleyip silinerek daha iyi tanımlamanız gerekir. Özellikle, bir çizgi değişebilir mi? Öyleyse, değiştirilen bir hattın nasıl ele alınmasını istersiniz? Kesinlikle çizgi yönelimli denetim yapıyorsanız, çizgi değiştirmek eski çizginin kaldırılması ve yeni çizginin eklenmesiyle aynıdır. Örneğin, ikiye bölünmüş bir çizgiyi nasıl ele almalı? İki 1 satır değişti mi? 2 satır değişti mi? 1 satır kaldırıldı ve 2 satır eklendi? Satırların hiçbir zaman değişmeyeceğini, yalnızca eklenip silineceğini garanti edemezseniz, bunun daha iyi tanımlamalar olmadan başarısızlığa mahkum olduğunu düşünüyorum.
Christopher Cashell,

Soruyu oldukça belirsiz buluyorum. Ancak sorunun en az bir yorumu ile cevaplanabilirdiff A B | grep '^[<>]'
kasperd

Arıyor olabilirsiniz comm.
Jenny D

@ChristopherCashell, sıralama düzenini yoksay; genellikle yaygın bir problem. Genellikle bu, tipik bir fark yapmadan önce her bir taraftaki bölümleri (çizgileri) ayırarak yapılır.
Pacerier

@Pacerier, Bundan emin misin? Yoksa tahmin ediyor musun? Sorguda sıralama veya arama düzeni hakkında hiçbir şey belirtilmez veya ima edilmez. Durduğu gibi, soru net değil ve birçok farklı şekilde yorumlanabilir. Ne sorduğundan emin olmadan , gerçek problemi çözebilecek veya çözmeyecek çözümler öneriyoruz. Ek olarak, orijinal posterin cevaplardan biri hakkındaki yorumu bunun sıralama ile ilgili olmadığını göstermektedir . "Değiştirilen" ile "değiştirilen" ve "silinen" anlamına gelmelidir.
Christopher Cashell,

Yanıtlar:


82

İletişim deneyin

Bakmanın başka bir yolu:

  • Yalnızca a dosyasındaki satırları göster: (yani a'dan silinen şey)

    comm -23 a b
    
  • Yalnızca b dosyasında bulunan satırları göster: (yani, b'ye ne eklenmiş)

    comm -13 a b
    
  • Yalnızca bir dosyada veya diğerinde bulunan satırları göster: (ancak her ikisini de değil)

    comm -3 a b | sed 's/^\t//'
    

(Uyarı: Dosyada aSEKME ile başlayan çizgiler varsa , (ilk SEKME) çıkıştan kaldırılır.)

Yalnızca sıralanmış dosyalar

NOT:comm Düzgün çalışması için iki dosyanın da sıralanması gerekir. Zaten sıralanmamışlarsa, sıralamanız gerekir:

sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted

Dosyalar çok uzunsa, bu, fazladan bir kopya gerektirdiğinden ve bu nedenle iki kat daha fazla disk alanı gerektirdiğinden oldukça yük olabilir.


5
Sadece doğru sonuçlar üretmek için (küçük harf duyarlı) Bu çözüm için her iki dosya sıralanabilir gerektiğini eklemek istedim
marmor

1
Yeterince modern kabuklarda, sıradaki gibi bir şeyi sıralayabilirsinizcomm -12 <(sort a) <(sort b)
Joshua Huber

14

commne istersen yapabilirsin. Man sayfasından:

AÇIKLAMA

Sıralanan dosyaları FILE1 ve FILE2 satır satır karşılaştırın.

Hiçbir seçenek olmadan, üç sütun çıktısı üretin. Bir sütun, FILE1'e özgü satırlar içerir, ikinci sütun FILE2'ye özgü satırlar içerir ve sütun üçü her iki dosyada da ortak olan satırları içerir.

Bu sütunlar ile suppressable olan -1, -2ve -3sırasıyla.

Örnek:

[root@dev ~]# cat a
common
shared
unique

[root@dev ~]# cat b
common
individual
shared

[root@dev ~]# comm -3 a b
    individual
unique

Ve sadece benzersiz satırları istiyorsanız ve hangi dosyada olduklarını umursamıyorsanız:

[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique

Man sayfasının dediği gibi, dosyalar önceden sıralanmalıdır.


9

Bağlamsız eklemeleri ve silmeleri göstermek için, satır numaraları, +, -, <,>! Vb, bu gibi diff kullanabilirsiniz:

diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt 

Örneğin, iki dosya verilir:

a.txt

Common
Common
A-ONLY
Common

b.txt

Common
B-ONLY
Common
Common

Aşağıdaki komut, a'dan kaldırılmış veya b'ye eklenen satırları gösterecektir:

diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt 

çıktı:

B-ONLY
A-ONLY

Bu biraz farklı komut a.txt dosyasından kaldırılan satırları gösterecektir:

diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt 

çıktı:

A-ONLY

Son olarak, bu komut a.txt dosyasına eklenen satırları gösterecektir.

diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt 

çıktı

B-ONLY

2

Varsayılan olarak ne fark budur ... Belki beyaz boşlukları yoksaymak için bazı bayraklar eklemeniz gerekir?

diff -b -B

boş satırları ve farklı sayıdaki boşlukları dikkate almamalı.


1
Hayır, DEĞİŞTİRİLMİŞ satırları da gösterir (karakterli veya dört farklı satırda). Sadece sol veya sağdaki çizgileri istiyorum.
C. Ross

2
DEĞİŞTİRİLEN bir dosyanın farklı sürümlerinin her birinin yalnızca solda veya sağda olduğunu iddia edebilirsiniz.
markdrayton

2
Farklılığın (veya başka bir aracın) değişimin ne olduğunu ve silinen bir satırın yerini neyin yeni bir satırla değiştirdiğini güvenilir bir şekilde söylemenin yolu yoktur.
Cian

1
Teknik olarak, diff "değiştirilmiş" bir satırı orijinal satır silinmiş ve yeni bir satır eklenmiş gibi ele alır ... bu yüzden teknik olarak sadece satır eklenmiş ve silinmiş satırları gösteriyor.
KFro

2

Hayır, diffaslında iki dosya arasındaki farkları birinin düşündüğü gibi göstermiyor. patchBir dosyayı bir başkasına dönüştürmek için kullanmak gibi bir araç için düzenleme komutları dizisi oluşturur .

Aradığınızı yapma girişiminin zorluğu, neyin silinmiş bir hatla değiştirildiğini ve ardından eklenmiş bir hat oluşturulduğunu tanımlamaktır. Ayrıca, satırlar birbirine eklendiğinde, eklendiğinde, silindiğinde ve değiştirildiğinde ne yapılmalı.


Benim düşüncelerim tam. Satırdaki karakterlerin yüzde kaçının, orijinalin değiştirilmesi yerine yenisi sayılması için değişmesi gerekir? Teknik olarak ortak bir karakteriniz olsa bile, onu bir silme ve ekleme yerine "değişiklik" olarak kabul edebilirsiniz.
Kamil Kisiel

1
diffKaynaklara baktığımdan bu yana çok zaman geçti , ama iki dosyanın senkronize kalacağı yerleri eşleştirmek için her türlü girintiyi hatırlıyor gibiyim. çizgiler Ancak (isteğe bağlı olarak) daraltılmış beyaz boşluk veya görmezden gelinme durumu dışında herhangi bir satır içi eşleşmeyi hatırlamıyorum. Ya da (belki) bu kelimelere etki eder. Her durumda, hepsi hakkında patchve "vgrep" sadece yolculuk için geliyor. Olabilir. Salı günü.
Dennis Williamson

2

Görsel karşılaştırma araçları iki dosyaya da uyuyor, böylece aynı sayıda satıra sahip ancak farklı içeriğe sahip bir segment değiştirilmiş bir segment olarak kabul edilecek. Eşleşen segmentler arasındaki tamamen yeni çizgiler, eklenmiş segmentler olarak kabul edilir.

Aynı zamanda sdiff komut satırı aracının çalışması, terminaldeki iki dosyanın yan yana karşılaştırılmasını gösterir. Değişen çizgiler | karakter. Eğer sadece A dosyasında bir çizgi varsa, ayırıcı karakter olarak <kullanılır. Sadece B dosyasında bir çizgi varsa, ayırıcı olarak> kullanılır. Dosyalarda <ve> karakteriniz yoksa, bunu yalnızca eklenen satırları göstermek için kullanabilirsiniz:

sdiff A B | grep '[<>]'

2

Teşekkürler senarvi, çözümünüz (oy kullanmadı) aslında bana tonlarca sayfadaki yaş aradıktan sonra ne istediğimi verdi.

Cevabınızı kullanarak, değiştirilen / eklenen / silinen şeylerin listesini almak için geldiğim şey budur. Örnek / etc / passwd dosyasının 2 versiyonunu kullanır ve ilgili kayıtların kullanıcı adını yazdırır.

#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'

"Bir çizgi değiştirildi" ve "bir çizginin kaldırılması ve başka bir çizginin altına veya üstüne eklenmesi " arasındaki farkın anlamsal olduğunu unutmayın. Genel bir metin tabanlı fark aracı bu durumları ayıramaz. Sonuç olarak, sdiff tabanlı cevabınız tüm durumlar için güvenilir bir şekilde çalışamaz.
Mikko Rantalainen

0

Bu özel formu genellikle yararlı buluyorum:

diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g

Örnek:

printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
     --new-line-format=$'+%l\n' \
     --unchanged-line-format='' \
     f g

Çıktı:

-b
-c
+B
+C
-e
-f
+E
+F

Böylece -hemen ardından gelen yeni satırlarla birlikte gelen eski satırları gösterir +.

Silme işlemi yapsaydık C:

printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
     --new-line-format=$'+%l\n' \
     --unchanged-line-format='' \
     f g

şuna benziyor:

-b
+B
+C
-e
-f
+E
+F

Format şu şekilde belgelenmiştir man diff:

       --line-format=LFMT
              format all input lines with LFMT`

ve:

       LTYPE is 'old', 'new', or 'unchanged'.
              GTYPE is LTYPE or 'changed'.

ve:

              LFMT (only) may contain:

       %L     contents of line

       %l     contents of line, excluding any trailing newline

       [...]

İlgili soru: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux

Ubuntu 18.04'te test edilmiştir.


-1

file1:

text670_1
text067_1
text067_2

file2:

text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1

kullanın:

diff -y file1 file2

Bu, düzeltici dosyalar için iki sütun gösterir.

Çıktı:

text670_1                           
                                  > text04_1
                                  > text04_2
                                  > text05_1
                                  > text05_2
text067_1                           text67_1
text067_2                           text67_2
                                  > text1000_1
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.