Jak porovnat dva textové soubory v terminálu Linux

Potřebujete zjistit, v čem se liší dvě verze textového souboru? Příkaz diff je přesně to, co hledáte. V tomto návodu si jednoduše ukážeme, jak používat příkaz diff v operačních systémech Linux a macOS.

Hlubší pohled na příkaz diff

Příkaz diff slouží k porovnání dvou souborů a generuje seznam odlišností mezi nimi. Přesněji řečeno, vytváří seznam změn, které by bylo nutné provést v prvním souboru, aby se shodoval s druhým. Pokud si to budete pamatovat, snadněji porozumíte výstupu příkazu diff. Tento příkaz byl navržen pro odhalování rozdílů mezi soubory zdrojového kódu a generuje výstup, který je čitelný a použitelný jinými programy, například příkazem patch. V tomto návodu se zaměříme na uživatelsky nejpřívětivější způsoby použití příkazu diff.

Pojďme se podívat na dva konkrétní soubory. Pořadí souborů zadaných v příkazovém řádku určuje, který soubor bude považován za „první“ a který za „druhý“. V níže uvedeném příkladu je alpha1 první soubor a alpha2 je druhý soubor. Oba soubory obsahují fonetickou abecedu, ale druhý soubor, alpha2, byl upraven, takže se oba soubory neshodují.

Porovnání souborů provedeme následujícím příkazem. Zadejte diff, mezeru, název prvního souboru, mezeru, název druhého souboru a stiskněte Enter.

diff alpha1 alpha2

Jak interpretovat tento výstup? Jakmile se seznámíte s tím, co hledat, není to složité. Každý rozdíl je uveden postupně v jednom sloupci a je označen. Štítek obsahuje čísla na obou stranách písmene, například 4c4. První číslo značí číslo řádku v alpha1 a druhé číslo je číslo řádku v alpha2. Písmeno uprostřed může být:

  • c: Řádek v prvním souboru je nutné změnit, aby se shodoval s řádkem v druhém souboru.
  • d: Řádek v prvním souboru je nutné odstranit, aby se shodoval s druhým souborem.
  • a: Do prvního souboru je nutné přidat další obsah, aby se shodoval s druhým souborem.

4c4 v našem příkladu udává, že řádek čtyři v souboru alpha1 je třeba změnit, aby odpovídal řádku čtyři v souboru alpha2. Toto je první nalezený rozdíl mezi soubory.

Řádky začínající znakem < odkazují na první soubor, alpha1. Řádek začínající znakem > odkazuje na druhý soubor, alpha2. Řádek > Dave nám říká, že slovo „Dave“ je obsahem čtvrtého řádku v alpha2. Stručně řečeno, musíme nahradit „Delta“ slovem „Dave“ na řádku čtyři v souboru alpha1, aby se tento řádek shodoval v obou souborech.

Další změna je označena 12c12. Stejnou logikou zjišťujeme, že řádek 12 v alpha1 obsahuje slovo „Lima“, zatímco řádek 12 v alpha2 obsahuje slovo „Linux“.

Třetí změna se týká řádku, který byl odstraněn z alpha2. Označení 21d20 lze interpretovat jako „řádek 21 je nutné odstranit z prvního souboru, aby se oba soubory synchronizovaly od řádku 20 dále.“

Čtvrtý rozdíl je označen 26a26,28. Tato změna se týká tří dalších řádků, které byly přidány do alpha2. Všimněte si 26,28 na štítku. Dvě čísla řádků oddělená čárkou představují rozsah čísel řádků. V tomto příkladu je rozsah od řádku 26 do řádku 28. Štítek je interpretován jako: „na řádku 26 v prvním souboru přidejte řádky 26 až 28 z druhého souboru.“ Zobrazí se tři řádky z alpha2, které je nutné přidat do alpha1. Obsahují slova „Quirk“, „Strange“ a „Charm“.

Rychlé příkazy na jeden řádek

Pokud chcete pouze zjistit, zda jsou dva soubory identické, použijte volbu -s (report identical files):

diff -s alpha1 alpha3

Volbu -q (brief) můžete použít k získání stručného oznámení o dvou rozdílných souborech:

diff -q alpha1 alpha2

Je důležité si uvědomit, že u dvou shodných souborů volba -q nehlásí žádný výstup.

Alternativní zobrazení

Volba -y (side-by-side) využívá jiné rozložení pro zobrazení rozdílů mezi soubory. Často je vhodné použít volbu -W (width) pro zobrazení vedle sebe, abyste omezili počet zobrazených sloupců. Tím se vyhnete nevzhledným zalomeným řádkům, které by ztěžovaly čitelnost výstupu. V následujícím příkladu příkaz diff vygeneruje zobrazení vedle sebe, omezené na 70 sloupců:

diff -y -W 70 alpha1 alpha2

První soubor v příkazovém řádku, alpha1, je zobrazen vlevo, a druhý soubor, alpha2, je zobrazen vpravo. Řádky z obou souborů se zobrazují vedle sebe. Vedle řádků v alpha2 jsou indikační znaky, které udávají, zda byl řádek změněn, odstraněn, nebo přidán.

  • |: Řádek, který byl změněn v druhém souboru.
  • <: Řádek, který byl odstraněn z druhého souboru.
  • >: Řádek, který byl přidán do druhého souboru a není v prvním.

Pokud preferujete stručnější souhrn rozdílů mezi soubory, použijte volbu --suppress-common-lines. Ta donutí diff zobrazit pouze změněné, přidané, nebo odstraněné řádky.

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

Přidání barev

Další nástroj s názvem colordiff přidává barevné zvýraznění výstupu diff. Díky tomu je mnohem snazší identifikovat řádky s odlišnostmi.

Pokud používáte Ubuntu nebo jinou distribuci založenou na Debianu, použijte apt-get k instalaci tohoto balíčku do vašeho systému. V ostatních distribucích Linuxu použijte nástroj pro správu balíčků vaší distribuce.

sudo apt-get install colordiff

Nástroj colordiff se používá stejně jako příkaz diff.

Colordiff je ve skutečnosti jen obal pro diff, který provádí veškerou práci v pozadí. Všechny volby příkazu diff tedy budou fungovat i s colordiff.

Zobrazení kontextu

Pro nalezení kompromisu mezi zobrazením všech řádků souborů a zobrazením pouze změněných řádků můžeme diff požádat o poskytnutí kontextu. Toho lze dosáhnout dvěma způsoby. Oba způsoby slouží stejnému účelu: zobrazují několik řádků před a za každým změněným řádkem. Díky tomu získáte přehled o tom, co se děje v souboru v místě, kde byl detekován rozdíl.

První metoda využívá volbu -c (context):

colordiff -c alpha1 alpha2

Výstup příkazu diff obsahuje hlavičku. V hlavičce jsou uvedeny názvy obou souborů a časy jejich úprav. Před názvem prvního souboru jsou hvězdičky (*) a před názvem druhého souboru jsou pomlčky (-). Hvězdičky a pomlčky slouží k označení souboru, ke kterému dané řádky patří.

Řádek s hvězdičkami a 1,7 uprostřed udává, že si prohlížíme řádky z alpha1. Konkrétně se jedná o řádky jedna až sedm. Slovo „Delta“ je označeno jako změněné. Vedle něj je vykřičník (!) a je zobrazen červeně. Před a za tímto řádkem jsou zobrazeny tři řádky nezměněného textu, takže můžeme vidět kontext tohoto řádku v souboru.

Řádek s pomlčkami a 1,7 uprostřed udává, že se nyní díváme na řádky z alpha2. Znovu se jedná o řádky jedna až sedm, přičemž slovo „Dave“ na řádku čtyři je označeno jako odlišné.

colordiff -C 2 alpha1 alpha2

Tři řádky kontextu nad a pod každou změnou jsou výchozí hodnotou. Můžete specifikovat, kolik řádků kontextu má diff poskytnout. K tomu slouží volba -C (context) s velkým písmenem „C“ následovaná požadovaným počtem řádků:

colordiff -u alpha1 alpha2

Druhá volba diff, která nabízí kontext, je volba -u (unified context).

Stejně jako v předchozím případě je na výstupu hlavička. Dva soubory jsou pojmenovány a jsou zobrazeny časy jejich úprav. Před názvem alpha1 jsou pomlčky (-) a před názvem alpha2 jsou znaménka plus (+). To nám říká, že pomlčky budou sloužit k odkazování na alpha1 a znaménka plus k odkazování na alpha2. V celém výpisu jsou roztroušené řádky začínající zavináčem (@). Tyto řádky označují začátek každého rozdílu a také nám říkají, které řádky jsou zobrazeny z každého souboru.

Zobrazí se tři řádky před a za řádkem označeným jako odlišný, abychom viděli kontext změněného řádku. V jednotném zobrazení jsou řádky s rozdíly zobrazeny nad sebou. Před řádkem z alpha1 je pomlčka a před řádkem z alpha2 je znaménko plus. Toto zobrazení dosahuje v osmi řádcích toho, co předchozí zobrazení potřebovalo patnáct.

colordiff -U 2 alpha1 alpha2

Jak byste očekávali, můžeme požádat diff o poskytnutí přesného počtu řádků sjednoceného kontextu, který chceme vidět. Pro tento účel použijte volbu -U (unified context) s velkým písmenem „U“ následovanou požadovaným počtem řádků:

Ignorování prázdných znaků a rozdílu ve velikosti písmen

colordiff -y -W 70 test4 test5

Analyzujme si další dva soubory, test4 a test5. Obsahují jména šesti superhrdinů.

Výsledky ukazují, že diff nachází shodné pouze řádky „Black Widow“, „Spider-Man“ a „Thor“. Změny jsou naznačeny u řádků „Captain America“, „Ironman“ a „The Hulk“.

V čem je tedy rozdíl? V souboru test5 je „Hulk“ napsán s malým „h“ a u „Captain America“ je mezi „Captain“ a „America“ mezera navíc. To je celkem zřejmé, ale co je špatného na řádku s „Ironman“? Nejsou zde žádné viditelné rozdíly. Pokud nevidíte rozdíly, odpovědí je obvykle prázdné místo. Na konci tohoto řádku je téměř jistě mezera nebo tabulátor.

Pokud vám na těchto rozdílech nezáleží, můžete diff instruovat, aby ignoroval konkrétní typy rozdílů na řádcích, včetně:

  • -i: Ignorovat rozdíly ve velikosti písmen.
  • -Z: Ignorovat prázdné znaky na konci řádků.
  • -b: Ignorovat změny v počtu prázdných znaků.
  • -w: Ignorovat všechny rozdíly v prázdných znacích.
colordiff -i -y -W 70 test4 test5

Znovu požádáme diff, aby zkontroloval tyto dva soubory, ale tentokrát ignoroval rozdíly ve velikosti písmen.

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

Řádky „The Hulk“ a „The Hulk“ jsou nyní považovány za shodné a malá písmena „h“ již nejsou označena jako rozdíl. Požádáme diff, aby také ignoroval prázdné znaky na koncích řádků.

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

Jak jsme tušili, prázdné znaky na konci řádku byly rozdílem v řádku s „Ironmanem“, protože rozdíl pro tento řádek již není označen. Zbývá už jen „Captain America“. Požádáme diff, aby ignoroval velikost písmen a všechny problémy s mezerami.

Když diff řekneme, aby ignoroval rozdíly, které nás nezajímají, sdělí nám, že pro naše účely se soubory shodují. Příkaz diff má mnohem více možností, ale většina z nich je zaměřena na generování strojově čitelného výstupu. Ty si můžete prozkoumat v manuálové stránce pro Linux.

Možnosti, které jsme použili v předchozích příkladech, vám umožní sledovat rozdíly mezi verzemi vašich textových souborů pomocí příkazového řádku a vizuální kontroly.