Jak mogę wyświetlić różnicę, aby wyświetlać tylko dodane i usunięte linie? Jeśli diff nie może tego zrobić, jakie narzędzie może?
diff A B | grep '^[<>]'
comm
.
Jak mogę wyświetlić różnicę, aby wyświetlać tylko dodane i usunięte linie? Jeśli diff nie może tego zrobić, jakie narzędzie może?
diff A B | grep '^[<>]'
comm
.
Odpowiedzi:
Inny sposób na to spojrzeć:
Pokaż linie, które istnieją tylko w pliku a: (tzn. Co zostało usunięte z a)
comm -23 a b
Pokaż linie, które istnieją tylko w pliku b: (tj. Co zostało dodane do b)
comm -13 a b
Pokaż linie, które istnieją tylko w jednym lub drugim pliku: (ale nie w obu)
comm -3 a b | sed 's/^\t//'
(Ostrzeżenie: jeśli plik a
ma wiersze rozpoczynające się od TAB, to (pierwsza TAB) zostanie usunięty z wyniku).
UWAGA: Aby pliki comm
działały poprawnie, oba pliki muszą zostać posortowane . Jeśli nie są jeszcze posortowane, należy je posortować:
sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted
Jeśli pliki są bardzo długie, może to stanowić duże obciążenie, ponieważ wymaga dodatkowej kopii, a zatem dwa razy więcej miejsca na dysku.
comm -12 <(sort a) <(sort b)
comm
może zrobić co chcesz. Ze strony podręcznika:
OPIS
Porównaj posortowane pliki PLIK1 i PLIK2 linia po linii.
Bez opcji utwórz wynik trójkolumnowy. Pierwsza kolumna zawiera wiersze unikalne dla PLIKU 1, druga kolumna zawiera wiersze unikalne dla PLIKU 2, a kolumna trzecia zawiera wiersze wspólne dla obu plików.
Te kolumny są suppressable z -1
, -2
i -3
odpowiednio.
Przykład:
[root@dev ~]# cat a
common
shared
unique
[root@dev ~]# cat b
common
individual
shared
[root@dev ~]# comm -3 a b
individual
unique
A jeśli chcesz tylko unikatowych linii i nie obchodzi Cię, w którym pliku się znajdują:
[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique
Jak mówi strona podręcznika, pliki muszą zostać wcześniej posortowane.
Aby wyświetlić uzupełnienia i usunięcia bez kontekstu, numery linii, +, -, <,>! itp., możesz użyć diff w następujący sposób:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
Na przykład, biorąc pod uwagę dwa pliki:
a.txt
Common
Common
A-ONLY
Common
b.txt
Common
B-ONLY
Common
Common
Następujące polecenie pokaże wiersze usunięte z a lub dodane do b:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
wynik:
B-ONLY
A-ONLY
To nieco inne polecenie pokaże linie usunięte z a.txt:
diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt
wynik:
A-ONLY
Na koniec to polecenie wyświetli wiersze dodane do pliku a.txt
diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt
wynik
B-ONLY
To właśnie diff domyślnie robi ... Może trzeba dodać kilka flag, aby zignorować białe znaki?
diff -b -B
powinny ignorować puste linie i inną liczbę spacji.
Nie, diff
tak naprawdę nie pokazuje różnic między dwoma plikami w sposób, w jaki można by pomyśleć. Tworzy sekwencję poleceń edycyjnych dla narzędzia takiego jak narzędzie patch
do zmiany jednego pliku na inny.
Trudność każdej próby zrobienia tego, czego szukasz, polega na tym, jak zdefiniować, co stanowi linię, która zmieniła się w porównaniu do linii usuniętej, po której następuje linia dodana. Co również zrobić, gdy wiersze są dodawane, usuwane i zmieniane obok siebie.
diff
źródła, ale wydaje mi się, że pamiętam wszystkie rodzaje zawirowań, aby śledzić, gdzie dwa pliki pasują do siebie w synchronizacji i myślę, że istnieje próg rezygnacji na podstawie tego, jak daleko od siebie są linie są. Ale nie pamiętam żadnego dopasowania wewnątrz linii, z wyjątkiem (opcjonalnie) zwiniętej białej spacji lub ignorowania wielkości liter. Lub (być może) słowa na to wpływają. W każdym razie chodzi o to patch
i „vgrep” pojawia się na przejażdżkę. Może. We wtorek.
Narzędzia porównywania wizualnego pasują do siebie dwa pliki, dzięki czemu segment o tej samej liczbie linii, ale o różnej zawartości będzie uważany za zmieniony segment. Całkowicie nowe linie między pasującymi segmentami są uważane za segmenty dodane.
Tak działa również narzędzie wiersza polecenia sdiff , które pokazuje porównanie dwóch plików w terminalu. Zmienione linie są oddzielone | postać. Jeśli wiersz istnieje tylko w pliku A, <jest stosowany jako znak separatora. Jeśli linia istnieje tylko w pliku B,> jest używany jako separator. Jeśli nie masz w plikach znaków <i>, możesz użyć tego, aby wyświetlić tylko dodane linie:
sdiff A B | grep '[<>]'
Dzięki senarvi, twoje rozwiązanie (nie głosowałem) faktycznie dało mi DOKŁADNIE to, czego chciałem po szukaniu wieku na mnóstwie stron.
Korzystając z twojej odpowiedzi, oto, co wymyśliłem, aby uzyskać listę rzeczy zmienionych / dodanych / usuniętych. W przykładzie użyto 2 wersji pliku / etc / passwd i wypisano nazwę użytkownika dla odpowiednich rekordów.
#!/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}'
Uważam, że ta konkretna forma jest często przydatna:
diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g
Przykład:
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
Wynik:
-b
-c
+B
+C
-e
-f
+E
+F
Pokazuje więc stare linie, -
po których następuje bezpośrednio nowa linia z +
.
Gdybyśmy usunęli 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
To wygląda tak:
-b
+B
+C
-e
-f
+E
+F
Format jest udokumentowany na man diff
:
--line-format=LFMT
format all input lines with LFMT`
i:
LTYPE is 'old', 'new', or 'unchanged'.
GTYPE is LTYPE or 'changed'.
i:
LFMT (only) may contain:
%L contents of line
%l contents of line, excluding any trailing newline
[...]
Powiązane pytanie: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux
Testowane w Ubuntu 18.04.
Plik 1:
text670_1
text067_1
text067_2
Plik2:
text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1
Posługiwać się:
diff -y file1 file2
To pokazuje dwie kolumny dla plików powtórzeń.
Wynik:
text670_1
> text04_1
> text04_2
> text05_1
> text05_2
text067_1 text67_1
text067_2 text67_2
> text1000_1