Jak porównać dwa pliki tekstowe w terminalu Linux

Chcesz porównać dwie wersje pliku tekstowego? W takim razie z pewnością przyda Ci się polecenie diff. W tym przewodniku pokażemy, jak łatwo korzystać z tego narzędzia na systemach Linux i macOS.

Wprowadzenie do diff

Polecenie diff służy do porównywania dwóch plików, generując listę różnic między nimi. Mówiąc bardziej precyzyjnie, tworzy zestaw zmian, jakie należy wprowadzić w pierwszym pliku, by uzyskać drugi plik. Zrozumienie tego kontekstu ułatwia interpretację wyników działania diff. Narzędzie to zostało stworzone z myślą o identyfikacji różnic w plikach kodu źródłowego oraz generowaniu wyników, które mogą być przetwarzane przez inne programy, takie jak polecenie patch. W tym przewodniku zaprezentujemy najbardziej przydatne i intuicyjne sposoby użycia diff.

Rozpocznijmy analizę dwóch plików. Kolejność, w jakiej podajemy pliki w poleceniu, określa, który z nich diff traktuje jako „pierwszy”, a który jako „drugi”. W poniższym przykładzie plik alpha1 jest pierwszym plikiem, a alpha2 drugim. Oba pliki zawierają dane w formacie alfabetu fonetycznego, jednak plik alpha2 został zmodyfikowany, co sprawia, że nie są one identyczne.

Możemy porównać pliki używając następującego polecenia. Wpisz diff, następnie spację, nazwę pierwszego pliku, kolejną spację, nazwę drugiego pliku i naciśnij Enter.

diff alpha1 alpha2

Jak odczytać ten wynik? Gdy już wiesz, na co zwracać uwagę, jest to prostsze niż się wydaje. Każda różnica jest przedstawiona w jednej kolumnie, a każda z nich jest oznaczona etykietą. Etykieta składa się z cyfr po obu stronach litery, na przykład 4c4. Pierwsza liczba odnosi się do numeru linii w pliku alpha1, a druga do numeru linii w pliku alpha2. Litera pomiędzy cyframi może mieć różne znaczenie:

c: Linia w pierwszym pliku musi zostać zmieniona, aby odpowiadała linii w drugim pliku.
d: Linia w pierwszym pliku musi zostać usunięta, aby pliki były zgodne.
a: Należy dodać dodatkową treść do pierwszego pliku, aby był zgodny z drugim plikiem.

W przypadku 4c4 nasza analiza mówi nam, że czwarta linia w pliku alpha1 musi zostać zmieniona, aby odpowiadała czwartej linii w pliku alpha2. To pierwsza z różnic, które udało się zidentyfikować.

Wiersze zaczynające się od oznaczają zawartość drugiego pliku, alpha2. Linia z tekstem „Dave” informuje nas, że słowo „Dave” znajduje się w czwartej linii pliku alpha2. Podsumowując, musimy zamienić „Delta” na „Dave” w czwartej linii pliku alpha1, aby pliki były zgodne.

Następna zmiana to 12c12. Stosując tę samą logikę, dowiadujemy się, że linia 12 w pliku alpha1 zawiera słowo „Lima”, podczas gdy w pliku alpha2 znajduje się słowo „Linux”.

Trzecia zmiana dotyczy usunięcia linii z pliku alpha2. Etykieta 21d20 oznacza, że „linia 21 musi zostać usunięta z pierwszego pliku, aby pliki były zgodne od linii 20.”

Czwarta różnica to 26a26,28. Ta zmiana dotyczy trzech dodatkowych linii, które zostały dodane do pliku alpha2. Numery 26,28 oddzielone przecinkiem oznaczają zakres numerów linii. W tym przypadku zakres obejmuje od 26 do 28. Etykieta mówi nam, że „w linii 26 w pierwszym pliku należy dodać linie od 26 do 28 z drugiego pliku”. Wskazuje to na trzy linie z pliku alpha2, które powinny zostać dodane do pliku alpha1, a są to słowa „Quirk”, „Strange” i „Charm”.

Krótko i na temat

Jeśli chcesz jedynie sprawdzić, czy dwa pliki są identyczne, użyj opcji -s (zgłoś identyczne pliki).

diff -s alpha1 alpha3

Możesz również skorzystać z opcji -q (krótkie), aby uzyskać zwięzły komunikat o tym, że pliki są różne.

diff -q alpha1 alpha2

Warto zauważyć, że przy porównywaniu dwóch identycznych plików opcja -q nie generuje żadnego komunikatu.

Alternatywna prezentacja

Opcja -y (widok obok siebie) stosuje inny układ do przedstawienia różnic między plikami. Często przydatne jest użycie opcji -W (szerokość), aby ograniczyć liczbę wyświetlanych kolumn. Dzięki temu unikamy nieczytelnych zawijanych wierszy. W poniższym przykładzie polecenie diff zostało skonfigurowane do wyświetlania obok siebie z ograniczeniem do 70 kolumn.

diff -y -W 70 alpha1 alpha2

Pierwszy plik, alpha1, znajduje się po lewej stronie, natomiast drugi plik, alpha2, po prawej. Wiersze z każdego pliku są wyświetlane obok siebie, a obok linii w alpha2 znajdują się oznaczenia wskazujące na zmiany, usunięcia lub dodania.

|: Linia, która została zmieniona w drugim pliku.
<: Linia, która została usunięta z drugiego pliku.
+: Linia, która została dodana do drugiego pliku i nie występuje w pierwszym pliku.

Jeśli preferujesz bardziej zwięzłe zestawienie różnic, skorzystaj z opcji –suppress-common-lines. Spowoduje to, że diff będzie wyświetlać tylko zmienione, dodane lub usunięte linie.

diff -y -W 70 --suppress-common-lines alpha1 alpha2

Dodaj kolor

Inne narzędzie, colordiff, dodaje kolorowe podświetlenie do wyjścia diff. Dzięki temu znacznie łatwiej jest dostrzec, które linie różnią się od siebie.

Aby zainstalować ten pakiet w systemie Ubuntu lub innej dystrybucji opartej na Debianie, użyj polecenia apt-get. W innych systemach Linux zastosuj odpowiednie narzędzie do zarządzania pakietami.

sudo apt-get install colordiff

Używaj colordiff w taki sam sposób, jak diff.

W rzeczywistości, colordiff jest oprogramowaniem opakowującym dla diff, co oznacza, że to diff wykonuje całą pracę w tle. Dlatego wszystkie opcje diff pozostają dostępne również w colordiff.

Zapewnienie kontekstu

Aby znaleźć równowagę między wyświetlaniem wszystkich linii w plikach a pokazywaniem tylko zmienionych linii, możemy poprosić diff o dostarczenie kontekstu. Istnieją dwa sposoby na to, oba mają na celu wyświetlenie kilku linii przed i po każdej zmienionej linii, co pozwala zobaczyć, co się dzieje w pliku w miejscu, gdzie wystąpiła różnica.

Pierwsza metoda to użycie opcji -c (kontekst skopiowany).

colordiff -c alpha1 alpha2

Wynik diff zawiera nagłówek, który pokazuje nazwy plików i ich czasy modyfikacji, z gwiazdkami (*) przed nazwą pierwszego pliku i myślnikami (-) przed nazwą drugiego pliku. Gwiazdki i myślniki wskazują, do którego pliku odnoszą się wiersze w wynikach.

Linia z gwiazdkami z 1,7 w środku oznacza, że patrzymy na linie z pliku alpha1, w tym przypadku od pierwszego do siódmego. Słowo „Delta” jest oznaczone jako zmienione, z wykrzyknikiem (!) obok, a jego kolor to czerwony. Równocześnie, trzy linie pozostałego tekstu wyświetlają się przed i po tej linii, co pozwala zobaczyć kontekst tej zmiany w pliku.

Linia z myślnikami z 1,7 oznacza, że teraz patrzymy na linie z pliku alpha2, również od pierwszego do siódmego, gdzie słowo „Dave” jest oznaczone jako inne.

colordiff -C 2 alpha1 alpha2

Możesz określić liczbę linii kontekstu, które chcesz zobaczyć, używając opcji -C (kontekst skopiowany) z wielką literą „C” oraz podając żądaną liczbę wierszy:

colordiff -u alpha1 alpha2

Jak w poprzednich przykładach, również tutaj pojawia się nagłówek z nazwami plików i ich czasami modyfikacji. Przed nazwą pliku alpha1 znajdują się myślniki (-), a przed nazwą pliku alpha2 znaki plus (+). To oznacza, że myślniki odnoszą się do pliku alpha1, a znaki plus do pliku alpha2. Na liście wyników znajdują się również wiersze rozpoczynające się od znaku (@), które oznaczają początek każdej różnicy i wskazują, które wiersze są wyświetlane z każdego pliku.

Wyświetlane są trzy linie przed i po linii oznaczonej jako zmieniona, co pozwala na zrozumienie kontekstu zmienionej linii. W ujednoliconym widoku różnice są ukazywane jedna nad drugą, gdzie wiersz z pliku alpha1 jest poprzedzony myślnikiem, a z pliku alpha2 znakiem plus. To podejście do wyświetlania różnic wymaga mniej miejsca niż pokazanie kontekstu w trybie skopiowanym.

colordiff -U 2 alpha1 alpha2

Wyjście colordiff z opcją -U 2

Ignorowanie białych znaków i wielkości liter

colordiff -y -W 70 test4 test5

Wyniki pokazują, że diff nie wykrywa różnic w liniach „Black Widow”, „Spider-Man” i „Thor”. Zmiany są natomiast widoczne w liniach „Captain America”, „Ironman” i „The Hulk”.

Co się zmieniło? W pliku test5 „Hulk” zapisano małą literą „h”, a między „Captain” a „America” dodano dodatkową spację. Różnice między plikami mogą być subtelne, jak w wypadku linii „Ironman”, gdzie nie widać żadnych zmian. W takiej sytuacji warto pamiętać, że jeśli nie dostrzegasz różnicy, prawdopodobnie chodzi o białe znaki, takie jak dodatkowa spacja lub tabulator na końcu linii.

Jeśli białe znaki nie mają dla Ciebie znaczenia, możesz skonfigurować diff, aby ignorował różne typy różnic, w tym:
-i: Ignorowanie różnic w wielkości liter.
-Z: Ignorowanie końcowych białych znaków.
-b: Ignorowanie zmian w ilości białych znaków.
-w: Ignorowanie wszystkich zmian odstępów.

colordiff -i -y -W 70 test4 test5

Wyniki colordiff pokazują, że różnice w wielkości liter nie są już uwzględniane.

colordiff -i -Z -y -W 70 test4 test5

Teraz linie „The Hulk” są traktowane jako zgodne, a różnice w wielkości liter nie są już wskazywane. Możemy również dodać opcję ignorowania końcowych białych znaków.

colordiff -i -w -y -W 70 test4 test5

Teraz, gdy końcowe spacje są ignorowane, diff nie wskazuje już różnicy w linii „Ironman”. Pozostaje tylko sprawdzić różnicę w linii „Captain America”. Informując diff, aby zignorował różnice, które nie są dla nas istotne, możemy uzyskać informację, że pliki w rzeczywistości są zgodne.

Polecenie diff oferuje znacznie więcej opcji, ale większość z nich dotyczy generowania wyjścia do przetwarzania przez maszyny. Można je sprawdzić w systemie Linux, w dokumentacji podręcznej.

Opcje, które wykorzystaliśmy w powyższych przykładach, umożliwiają dokładne śledzenie różnic między wersjami plików tekstowych przy użyciu wiersza poleceń oraz ludzkiego oka.


newsblog.pl