Polecenie diff: porównywanie plików, format łatki diff -u i opcje
Polecenie diff to polecenie Linuksa, które porównuje dwa pliki wiersz po wierszu i wypisuje tylko wiersze różniące się. Porównanie przez diff starego i nowego pliku, które naśladują konfigurację serwera WWW, pokazało trzy zmienione miejsca w trzech wierszach 2,3c2,3, 5d4 i 6a6, a w pliku łatki zapisanym z opcją -u te same zmiany były uporządkowane znakami minus i plus.
Nazwy i zawartość plików w poniższych wynikach oraz folder roboczy /root/work to wartości przykładowe. Wszystkie porównywane pliki to małe pliki utworzone do testów.
1️⃣ Podstawowe użycie polecenia diff i czytanie wyniku
Podstawowa postać polecenia to kolejno diff, opcje, pierwszy plik i drugi plik. Polecenie wypisuje z numerami wierszy, które wiersze trzeba zmienić, usunąć lub dodać, żeby pierwszy plik stał się taki sam jak drugi.
Dwa pliki użyte do porównania to sześciowierszowe pliki naśladujące konfigurację serwera WWW.
cd /root/workcat config-old.conf# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warncat config-new.conf# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache onOba pliki porównano bez opcji.
diff config-old.conf config-new.conf2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache onecho $?1W wyniku na przemian pojawiają się wiersze pozycji i wiersze treści. Środkowa litera wiersza pozycji to c dla zmiany, d dla usunięcia i a dla dodania; na lewo od litery stoją numery wierszy pierwszego pliku, na prawo drugiego. Gdy są różnice, kod wyjścia wynosi 1.
| Wynik | Znaczenie |
|---|---|
| 2,3c2,3 | Zmienia wiersze 2–3 pierwszego pliku na wiersze 2–3 drugiego pliku (change) |
| 5d4 | Usuwa wiersz 5 pierwszego pliku (delete). Po usunięciu zgadza się z miejscem za wierszem 4 drugiego pliku |
| 6a6 | Dodaje wiersz 6 drugiego pliku za wierszem 6 pierwszego pliku (add) |
| < wiersz | Wiersz z pierwszego pliku |
| > wiersz | Wiersz z drugiego pliku |
| --- | Granica między stroną pierwszego pliku a stroną drugiego pliku w zmienianych wierszach (c) |
Przy porównaniu plików o tej samej zawartości nic nie jest wypisywane, a polecenie kończy się kodem wyjścia 0.
diff config-old.conf config-copy.confecho $?0Po podaniu pliku, który nie istnieje, pojawia się komunikat o błędzie, a kod wyjścia wynosi 2.
diff config-old.conf nosuch.confdiff: nosuch.conf: No such file or directoryecho $?2W skrypcie te trzy wartości pozwalają odróżnić: takie same, różne i błąd.
2️⃣ Format ujednolicony diff -u i plik łatki
Domyślny wynik zawiera tylko zmienione wiersze, więc w pliku konfiguracyjnym liczącym setki wierszy trudno znaleźć, przy którym ustawieniu się znajdują. Po dodaniu -u wynik ma format ujednolicony (unified), który łączy zmienione wiersze z maksymalnie trzema wierszami przed nimi i po nich.
diff -u config-old.conf config-new.conf--- config-old.conf 2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf 2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
# app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
root /var/www/html
-gzip off
log_level warn
+cache onDwa wiersze nagłówka (---, +++) zawierają nazwy i czas modyfikacji obu plików, a wiersz @@ -1,6 +1,6 @@ oznacza blok (hunk), który łączy 6 wierszy od wiersza 1 pierwszego pliku z 6 wierszami od wiersza 1 drugiego pliku. W wierszach poniżej początkowy - oznacza wiersz usunięty z pierwszego pliku, + wiersz dodany do drugiego pliku, a spacja wiersz identyczny w obu plikach.
-c to format kontekstowy (context). Blok pierwszego pliku i blok drugiego pliku są wypisywane osobno, z wykrzyknikiem przed zmienionymi wierszami, minusem przy usuniętych i plusem przy dodanych.
diff -c config-old.conf config-new.conf*** config-old.conf Thu Oct 29 02:24:50 2026
--- config-new.conf Thu Oct 29 02:24:50 2026
***************
*** 1,6 ****
# app config
! listen 80
! server_name example.com
root /var/www/html
- gzip off
log_level warn
--- 1,6 ----
# app config
! listen 443
! server_name example.com www.example.com
root /var/www/html
log_level warn
+ cache onPrzy tych samych zmianach wynik -c był dłuższy niż -u, bo niezmienione wiersze pojawiają się po razie w każdym z dwóch bloków.
Zapisanie wyniku -u do pliku daje od razu plik łatki. Także po skierowaniu wyniku do pliku kod wyjścia diff nadal wynosi 1.
diff -u config-old.conf config-new.conf > /root/work/config.patchecho $?1cat /root/work/config.patch--- config-old.conf 2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf 2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
# app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
root /var/www/html
-gzip off
log_level warn
+cache onZawartość zapisanego pliku jest taka sama jak wynik -u wypisany na ekranie. Po przekazaniu tego pliku poleceniu patch pierwszy plik można doprowadzić do tej samej zawartości co drugi.
3️⃣ Opcje diff oraz ignorowanie spacji i wielkości liter
Przy ręcznym przepisywaniu ustawień powstają wiersze o tej samej treści, różniące się tylko wielkością liter lub spacjami. W drugiej parze plików przykładowych wielkie L w pierwszym wierszu zmieniono na małe, jedną spację w drugim wierszu na dwie i dodano jeden pusty wiersz.
cat case-a.txtListen 80
ServerName example.com
DocumentRoot /var/www/htmlcat case-b.txtlisten 80
ServerName example.com
DocumentRoot /var/www/htmldiff case-a.txt case-b.txt1,2c1,3
< Listen 80
< ServerName example.com
---
> listen 80
> ServerName example.com
>Przy porównaniu bez opcji wiersze 1–2, które znaczą to samo, też pojawiają się jako zmienione. Po zignorowaniu wielkości liter przez -i wiersz Listen znika i zostaje tylko wiersz 2 pierwszego pliku.
diff -i case-a.txt case-b.txt2c2,3
< ServerName example.com
---
> ServerName example.com
>Po dodaniu -w ignorowane są wszystkie spacje w wierszu, więc wiersz ServerName też staje się taki sam i zostaje tylko jeden pusty wiersz dodany w wierszu 3. Po wstawieniu zamiast -w opcji -b, która ignoruje tylko liczbę spacji, wynik dla tych plików był taki sam.
diff -i -w case-a.txt case-b.txt2a3
>Po dodaniu jeszcze -B ignorowane są także różnice w pustych wierszach, więc polecenie zakończyło się bez wyniku, z kodem wyjścia 0.
diff -i -w -B case-a.txt case-b.txtecho $?0Do oglądania dwóch plików obok siebie, po lewej i po prawej, służy -y. Domyślna szerokość to 130 kolumn, dlatego zmniejszono ją przez -W 70.
diff -y -W 70 config-old.conf config-new.conf# app config # app config
listen 80 | listen 443
server_name example.com | server_name example.com www.ex
root /var/www/html root /var/www/html
gzip off <
log_level warn log_level warn
> cache onPionowa kreska (|) pośrodku oznacza zmieniony wiersz, < wiersz obecny tylko w pierwszym pliku, a > wiersz obecny tylko w drugim pliku. Po zwężeniu długie wiersze są obcinane. Wiersz server_name pojawił się po prawej tylko do www.ex.
Po dodaniu --suppress-common-lines takie same wiersze są pomijane i zostają tylko różne.
diff -y --suppress-common-lines -W 70 config-old.conf config-new.conflisten 80 | listen 443
server_name example.com | server_name example.com www.ex
gzip off <
> cache onDo sprawdzenia tylko tego, czy pliki są takie same, czy różne, a nie treści różnic, służy -q. Gdy pliki są takie same, -q nic nie wypisuje, więc do uzyskania wiersza z informacją, że są identyczne, służy -s.
diff -q config-old.conf config-new.confFiles config-old.conf and config-new.conf differdiff -s config-old.conf config-copy.confFiles config-old.conf and config-copy.conf are identicalOpcje zebrano w dwóch kartach poniżej.
| Opcja | Kopiuj | Opis |
|---|---|---|
| -u, --unified | Wypisuje w formacie ujednoliconym, który łączy zmienione wiersze z maksymalnie trzema wierszami przed nimi i po nich | |
| -c, --context | Format kontekstowy, który wypisuje osobno blok pierwszego pliku i blok drugiego pliku | |
| -i, --ignore-case | Ignoruje różnice w wielkości liter | |
| -w, --ignore-all-space | Ignoruje wszystkie spacje w wierszu | |
| -b, --ignore-space-change | Ignoruje tylko różnice w liczbie spacji | |
| -B, --ignore-blank-lines | Ignoruje różnice w pustych wierszach | |
| -y, --side-by-side | Wypisuje dwa pliki obok siebie, po lewej i po prawej | |
| -W, --widthNUM | Ustawia szerokość wyniku obok siebie. Wartość domyślna to 130 kolumn | |
| --suppress-common-lines | W wyniku obok siebie pomija takie same wiersze i wypisuje tylko różne | |
| -q, --brief | Wypisuje tylko, czy pliki są takie same, czy różne. Gdy są takie same, nic nie wypisuje | |
| -s, --report-identical-files | Gdy dwa pliki są takie same, wypisuje wiersz z informacją, że są identyczne | |
| -r, --recursive | Porównuje także pliki w podfolderach |
| Opcja | Kopiuj | Opis |
|---|---|---|
| -U, --unifiedNUM | Ustawia liczbę wierszy przed i po wypisywanych razem w formacie ujednoliconym. Wartość domyślna to 3 | |
| -N, --new-file | Traktuje plik, którego brakuje po jednej stronie, jak pusty plik | |
| -x, --excludePAT | Wyklucza z porównania pliki o nazwach pasujących do wzorca | |
| -I, --ignore-matching-linesRE | Ignoruje różnicę, jeśli wszystkie zmienione wiersze pasują do wyrażenia regularnego | |
| -Z, --ignore-trailing-space | Ignoruje spacje na końcu wiersza | |
| -E, --ignore-tab-expansion | Ignoruje różnice powstałe przez zamianę tabulatorów na spacje | |
| -a, --text | Traktuje wszystkie pliki jak tekst | |
| --strip-trailing-cr | Usuwa znak powrotu karetki z końca wiersza przed porównaniem | |
| --colorWHEN | Koloruje wynik. WHEN to never, always lub auto | |
| -v, --version | Wypisuje informacje o wersji |
🔲 Symulator polecenia diff
W symulatorze poniżej można samodzielnie wpisać diff z plikami przykładowymi z artykułu. Można zapisać plik łatki przez -u albo porównać przez -i -w -B i -rq, a po dodaniu wiersza do config-new.conf i ponownym porównaniu pojawia się zmieniony wynik.
4️⃣ Porównywanie folderów przez diff -r
Przy porównywaniu wielu plików naraz, na przykład przed wdrożeniem plików witryny i po nim, zamiast plików podaje się nazwy folderów. Przykładowe foldery site-v1 i site-v2 zawierają oba index.html i folder css, a about.html i contact.html są tylko po jednej stronie.
diff site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
Common subdirectories: site-v1/css and site-v2/css
diff site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>Przy porównaniu folderów bez opcji pliki obecne tylko po jednej stronie pojawiają się jako wiersze [Only in], a podfoldery tylko jako wiersze [Common subdirectories]; pliki w podfolderach nie są porównywane. Dla index.html, który jest pod tą samą nazwą w obu folderach, różnice są wypisywane pod wierszem [diff site-v1/index.html site-v2/index.html]. Po dodaniu -r wypisywana jest też zmieniona wartość koloru w style.css w folderze css.
diff -r site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
diff -r site-v1/css/style.css site-v2/css/style.css
2c2
< h1 { color: #222; }
---
> h1 { color: #0a58ca; }
diff -r site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>W folderze z wieloma plikami najpierw sprawdza się przez -rq listę zmienionych plików, a potem ponownie porównuje przez diff tylko potrzebne pliki.
diff -rq site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
Files site-v1/css/style.css and site-v2/css/style.css differ
Files site-v1/index.html and site-v2/index.html differ🔢 FAQ & polecane treści
Linux · Tekst
Polecenie grep w Linuksie
Jak używać grep, żeby w pliku tekstowym, takim jak plik dziennika, znaleźć i wypisać tylko wiersze zawierające szukany ciąg znaków.
Linux · Tekst
Polecenie sort w Linuksie: sortowanie plików
Opcje i przykłady sort do sortowania zawartości pliku alfabetycznie, rosnąco lub malejąco.
Linux · Tekst
Polecenie uniq w Linuksie
Jak używać uniq, aby z powtarzających się wierszy zostawić tylko jeden i policzyć opcją -c, ile razy się powtarzają.
ℹ️ Informacja o linkach partnerskich
Treści tej witryny zawierają linki partnerskie. Jeśli odwiedzający kupi produkt lub usługę przez taki link, witryna otrzymuje od sprzedawcy prowizję. Kwota płacona przy tym przez kupującego (podczas promocji spada↓) nie wzrasta. Podane ceny, rabaty i dostępność odnoszą się do chwili pisania i mogą różnić się od stanu faktycznego, dlatego przed zakupem sprawdź je u sprzedawcy. Produkty wybieramy i oceniamy według własnych kryteriów, a prowizja nie wpływa ani na kolejność prezentacji, ani na treść ocen.