Cum se compară două fișiere text în terminalul Linux

Doriți să identificați deosebirile dintre două variante ale unui document text? În acest caz, comanda `diff` este instrumentul de care aveți nevoie. Acest ghid practic vă va demonstra cum să utilizați `diff` pe sistemele Linux și macOS, într-un mod simplu și eficient.

Analizând în profunzime comanda `diff`

Comanda `diff` analizează două fișiere și prezintă o listă cu diferențele dintre ele. Mai precis, generează o listă cu modificările care ar trebui efectuate asupra primului fișier pentru a-l alinia cu al doilea. Înțelegând acest aspect, veți interpreta mai ușor rezultatele oferite de `diff`. Această comandă a fost concepută pentru a detecta deosebirile dintre fișierele sursă de cod și a genera un output care poate fi citit și procesat de alte programe, precum comanda patch. În acest tutorial, vom examina cele mai accesibile metode de a utiliza `diff`.

Să trecem direct la treabă și să analizăm două fișiere. Ordinea fișierelor specificată în linia de comandă stabilește care fișier este considerat „primul fișier” și care este „al doilea fișier”. În exemplul de mai jos, `alpha1` este primul fișier, iar `alpha2` este al doilea. Ambele fișiere conțin alfabetul fonetic, dar al doilea fișier, `alpha2`, a fost editat suplimentar, astfel încât cele două fișiere să nu fie identice.

Putem compara fișierele folosind următoarea comandă. Introduceți `diff`, un spațiu, numele primului fișier, un spațiu, numele celui de-al doilea fișier, apoi apăsați Enter.

diff alpha1 alpha2

Cum interpretăm această ieșire? Odată ce înțelegeți structura, devine destul de simplu. Fiecare deosebire este afișată pe o linie separată, într-o singură coloană și este etichetată. Eticheta include numere separate printr-o literă, cum ar fi `4c4`. Primul număr reprezintă numărul liniei în `alpha1`, iar al doilea număr, numărul liniei în `alpha2`. Litera din mijloc poate fi:

`c`: Linia din primul fișier trebuie modificată pentru a corespunde cu linia din al doilea fișier.
`d`: Linia din primul fișier trebuie ștearsă pentru a corespunde cu al doilea fișier.
`a`: Trebuie adăugat conținut suplimentar la primul fișier pentru ca acesta să corespundă cu al doilea fișier.

Eticheta `4c4` din exemplul nostru ne indică faptul că linia patru din `alpha1` trebuie modificată pentru a corespunde liniei patru din `alpha2`. Aceasta este prima deosebire identificată între cele două fișiere.

Liniile care încep cu `>` fac referire la al doilea fișier, `alpha2`. Linia `Dave` ne informează că în linia patru din `alpha2` se află cuvântul `Dave`. Pentru a rezuma, trebuie să înlocuim `Delta` cu `Dave` pe linia patru din `alpha1`, pentru a le face identice.

Următoarea modificare este indicată de `12c12`. Conform aceleiași logici, aceasta ne spune că linia 12 din `alpha1` conține cuvântul `Lima`, dar linia 12 din `alpha2` conține cuvântul `Linux`.

A treia modificare se referă la o linie care a fost ștearsă din `alpha2`. Eticheta `21d20` se interpretează ca „linia 21 trebuie ștearsă din primul fișier, astfel încât ambele fișiere să fie sincronizate începând cu linia 20”.

A patra deosebire este marcată cu `26a26,28`. Această modificare face referire la trei linii suplimentare care au fost adăugate la `alpha2`. Observați `26,28` în etichetă. Numerele pe două linii separate prin virgulă reprezintă un interval de numere de linie. În acest exemplu, intervalul este de la linia 26 la linia 28. Eticheta este interpretată ca „la linia 26 din primul fișier, adăugați liniile 26 până la 28 din al doilea fișier”. Ni se afișează cele trei linii din `alpha2` care trebuie adăugate la `alpha1`. Acestea conțin cuvintele `Quirk`, `Strange` și `Charm`.

Comenzi rapide

Dacă doriți doar să verificați dacă două fișiere sunt identice, utilizați opțiunea `-s` (afișează fișierele identice).

diff -s alpha1 alpha3

Puteți utiliza opțiunea `-q` (scurt) pentru a obține o declarație la fel de concisă referitoare la două fișiere diferite.

diff -q alpha1 alpha2

Trebuie să țineți cont de faptul că, atunci când comparați două fișiere identice, opțiunea `-q` (scurt) nu afișează absolut nimic.

O altă modalitate de vizualizare

Opțiunea `-y` (alăturat) utilizează un format diferit pentru a prezenta deosebirile dintre fișiere. De obicei, este util să folosiți opțiunea `-W` (lățime) cu afișarea alăturată, pentru a limita numărul de coloane afișate. Acest lucru previne liniile prea lungi, care pot face dificilă citirea rezultatului. În exemplul de mai jos, am indicat `diff` să genereze o afișare alăturată și să limiteze rezultatul la 70 de coloane.

diff -y -W 70 alpha1 alpha2

Primul fișier din linia de comandă, `alpha1`, este afișat în stânga, iar al doilea fișier, `alpha2`, este afișat în dreapta. Liniile din fiecare fișier sunt prezentate una lângă alta. Lângă liniile din `alpha2` care au fost modificate, șterse sau adăugate, apar caractere indicatoare:

`|`: O linie care a fost modificată în al doilea fișier.
`<`: O linie care a fost ștearsă din al doilea fișier.
`>`: O linie care a fost adăugată la al doilea fișier, dar care nu se regăsește în primul fișier.

Dacă preferați o prezentare alăturată mai compactă a deosebirilor dintre fișiere, utilizați opțiunea `–suppress-common-lines`. Aceasta forțează `diff` să afișeze doar liniile modificate, adăugate sau șterse.

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

Adăugarea de culoare

Un alt instrument util, numit `colordiff`, adaugă evidențierea culorilor la output-ul `diff`. Acest lucru simplifică identificarea liniilor care conțin deosebiri.

Utilizați `apt-get` pentru a instala acest pachet pe sistemul dumneavoastră, dacă utilizați Ubuntu sau o altă distribuție bazată pe Debian. Pentru alte distribuții Linux, folosiți instrumentul de gestionare a pachetelor al distribuției dumneavoastră Linux.

sudo apt-get install colordiff

Utilizați `colordiff` în același mod în care ați utiliza `diff`.

De fapt, `colordiff` este un înveliș pentru `diff`, iar `diff` realizează toate operațiunile din fundal. Din acest motiv, toate opțiunile `diff` vor funcționa și cu `colordiff`.

Oferirea de context

Pentru a găsi o cale de mijloc între afișarea tuturor liniilor din fișiere și afișarea doar a liniilor modificate, putem solicita `diff` să ofere un anumit context. Există două modalități de a face acest lucru. Ambele metode realizează același scop, și anume, afișarea câtorva linii înainte și după fiecare linie modificată. Veți putea observa ce se întâmplă în fișier în zona în care a fost detectată o diferență.

Prima metodă utilizează opțiunea `-c` (context copiat).

colordiff -c alpha1 alpha2

Output-ul `diff` are un antet. Antetul afișează cele două nume de fișiere și orele la care acestea au fost modificate. Apar asteriscuri (*) înainte de numele primului fișier și linii orizontale (-) înainte de numele celui de-al doilea fișier. Asteriscurile și liniuțele vor fi folosite pentru a indica fișierul de care aparțin liniile din rezultat.

O linie de asteriscuri cu `1,7` în mijloc ne indică faptul că analizăm liniile din `alpha1`. Mai exact, ne uităm la liniile de la unu până la șapte. Cuvântul `Delta` este marcat ca fiind modificat. Are un semn de exclamare (!) lângă el și este afișat cu roșu. Sunt prezentate trei linii de text nemodificat înainte și după acea linie, astfel încât să putem vedea contextul acelei linii în fișier.

Linia de linii orizontale cu `1,7` în mijloc ne arată că acum analizăm liniile din `alpha2`. Din nou, ne uităm la liniile de la unu până la șapte, cu cuvântul `Dave` de pe linia patru marcat ca fiind diferit.

colordiff -C 2 alpha1 alpha2

Trei linii de context deasupra și sub fiecare modificare reprezintă valoarea implicită. Puteți specifica câte linii de context doriți să ofere `diff`. Pentru a face acest lucru, folosiți opțiunea `-C` (context copiat) cu un „C” majuscul și specificați numărul de linii dorit:

colordiff -u alpha1 alpha2

A doua opțiune a `diff` care oferă context este opțiunea `-u` (context unificat).

Ca și înainte, output-ul conține un antet. Cele două fișiere sunt numite, iar orele de modificare sunt afișate. Există linii orizontale (-) înainte de numele `alpha1` și semne plus (+) înainte de numele `alpha2`. Acest lucru ne indică faptul că liniuțele vor fi folosite pentru a face referire la `alpha1`, iar semnele plus vor fi folosite pentru a face referire la `alpha2`. În toată lista sunt împrăștiate linii care încep cu simbolul (@). Aceste linii marchează începutul fiecărei deosebiri. De asemenea, ne indică ce linii sunt afișate din fiecare fișier.

Ni se prezintă cele trei linii dinaintea și după linia marcată ca fiind diferită, astfel încât să putem observa contextul liniei modificate. În modul de vizualizare unificat, liniile cu diferențe sunt afișate una deasupra celeilalte. Linia din `alpha1` este precedată de o liniuță, iar linia din `alpha2` este precedată de un semn plus. Această afișare realizează în opt rânduri ceea ce necesita cincisprezece rânduri în cazul afișării contextului copiat.

colordiff -U 2 alpha1 alpha2

Așa cum vă așteptați, putem solicita `diff` să ofere exact numărul de linii de context unificat pe care dorim să le vedem. Pentru a face acest lucru, utilizați opțiunea `-U` (context unificat) cu un „U” majuscul și specificați numărul de linii dorit:

Ignorarea spațiilor și a majusculelor

colordiff -y -W 70 test4 test5

Să analizăm alte două fișiere, `test4` și `test5`. Acestea conțin numele a șase supereroi.

Rezultatele indică faptul că `diff` nu identifică nicio deosebire la liniile `Black Widow`, `Spider-Man` și `Thor`. Schimbările sunt semnalate la liniile `Captain America`, `Ironman` și `The Hulk`.

Deci, ce este diferit? În fișierul `test5`, `Hulk` este scris cu „h” minuscul, iar `Captain America` are un spațiu suplimentar între „Captain” și „America”. Bun, este destul de clar, dar ce este în neregulă cu linia `Ironman`? Nu există diferențe vizibile. Iată o regulă utilă: dacă nu vedeți diferența, răspunsul este spațiul alb. Aproape sigur există un spațiu suplimentar sau două, sau un caracter tabulator la sfârșitul acelei linii.

Dacă nu vă deranjează aceste aspecte, puteți indica `diff` să ignore anumite tipuri de deosebiri la nivel de linie, inclusiv:
`-i`: Ignoră diferențele de scriere cu majuscule sau minuscule.
`-Z`: Ignoră spațiile albe de la finalul liniei.
`-b`: Ignoră modificările privind cantitatea de spațiu alb.
`-w`: Ignoră toate modificările spațiilor albe.

colordiff -i -y -W 70 test4 test5

Să solicităm `diff` să verifice din nou cele două fișiere, dar de această dată să ignore orice deosebire la nivel de scriere cu majuscule și minuscule.

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

Liniile cu `Hulk` și `hulk` sunt acum considerate o potrivire, și nu mai este semnalată nicio diferență în ceea ce privește scrierea cu „h” minuscul. Să solicităm `diff` să ignore și spațiul alb de la sfârșitul liniei.

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

După cum era de așteptat, spațiul alb de la sfârșitul liniei a fost cauza diferenței pentru linia `Ironman`, deoarece `diff` nu mai semnalează nicio diferență pentru acea linie. Acest lucru îl lasă pe `Captain America`. Să solicităm `diff` să ignore majusculele și minusculele și, de asemenea, toate problemele legate de spațiile albe.

Indicând `diff` să ignore deosebirile care nu ne interesează, `diff` ne comunică faptul că, în scopurile noastre, fișierele sunt identice. Comanda `diff` are mult mai multe opțiuni, dar majoritatea fac referire la generarea de rezultate care pot fi citite de mașină. Acestea pot fi analizate în pagina de manual Linux.

Opțiunile pe care le-am folosit în exemplele de mai sus vă vor permite să urmăriți toate deosebirile dintre versiunile fișierelor text, folosind linia de comandă și proprii ochi.