Jak zrobić wyjście „różnicowe” linia po linii?

1

Mam na pozór proste pytanie, na które nie mogę znaleźć odpowiedzi.

Powiedz, mam dwa pliki:

A
B
C
D

i

A
X
Y
D

Kiedy je uruchamiam diff -U 1000, otrzymuję:

 A
-B
-C
+X
+Y
 D

Zamiast tego chciałbym uzyskać:

 A
-B
+X
-C
+Y
 D

Duże zdjęcie, aby zrozumieć, co próbuję osiągnąć: mam zaplanowany skrypt, który działa smartctlna moich dyskach twardych, przechowuję dane historyczne i porównuję je. Tak więc zmienione wiersze są rzeczywiście pojedynczymi zamiennikami odpowiednich wierszy wcześniejszego pliku:

-  3 Spin_Up_Time      0x0027   173   168   021    Pre-fail  Always    -    2350
-  4 Start_Stop_Count  0x0032   096   096   000    Old_age   Always    -    4445
+  3 Spin_Up_Time      0x0027   172   168   021    Pre-fail  Always    -    2358
+  4 Start_Stop_Count  0x0032   096   096   000    Old_age   Always    -    4461
bytebuster
źródło

Odpowiedzi:

0

Skończyłem z dwuetapowym procesem: przejście do, git diffa następnie przetworzenie go za pomocą skryptu AWK:

     git diff --word-diff=porcelain -U10000 %1 %2  |
     awk -f mysmartdiff.awk;

Pierwszy krok zwraca wynik w następującej formie:

~
   3 Spin_Up_Time            0x0027
-172
+173
    168   021    Pre-fail  Always       -
-2358
+2333

a drugi skrypt robi to:

zrzut ekranu końcowego wyniku

mysmartdiff.awkScenariusz jest następujący:

BEGIN {
    DEBUG=0
    l1=""
    l2=""
    old=""
    new=""
}
function dprint(s) { if(DEBUG) {print s > "/dev/stderr"} }

function appendDiff() {
    if(length(old)!=0 || length(new)!=0) {
        l1 = l1"\033[1;31m"old"\033[0m"
        l2 = l2"\033[1;32m"new"\033[0m"
        old="";new="";
    }
}
{
    dprint(">>>>>>>>>>>>>>")
    dprint("ORIG: " $0)
    if(match($0, /^ /)) {
        appendDiff();
        l1 = l1""substr($0,2)
        l2 = l2""gensub(/[^-]/, " ", "g", substr($0,2)); ## leave '-' to aid further space trimming
    } else if(match($0, /^~/)) {
        appendDiff();
        print l1;
        if(l2 !~ /^[ -]+$/) {
            print l2;
        }
        l1=""
        l2=""
    } else if(match($0, /^-/)) {
        old=substr($0,2);
    } else if(match($0, /^+/)) {
        new=substr($0,2);
    }
}
bytebuster
źródło