Fájlok tartalmának összehasonlítása parancssorból

Képzelje el, hogy egy összetett projektbe van belevetve, és hirtelen rájön, hogy valami nem stimmel. Egy konfigurációs fájlt módosított, egy kódot frissített, vagy esetleg két adatkészlet között keresi a különbséget. Honnan tudja, mi változott pontosan? Hogyan azonosítja a hibát? Ilyenkor jönnek jól a parancssori eszközök, amelyek pillanatok alatt feltárják a fájlok tartalmának apró (vagy éppen óriási) eltéréseit.

A fájlok tartalmának összehasonlítása nem csupán a szoftverfejlesztők és rendszergazdák kiváltsága. Adatbázis-exportok ellenőrzése, logfájlok elemzése, dokumentumok verziókövetése – mindezekben a helyzetekben kulcsfontosságú, hogy gyorsan és hatékonyan azonosítsuk a változásokat. Bár léteznek kényelmes grafikus felületek (mint például a Meld vagy a WinMerge), a parancssori eszközök ereje, sebessége és automatizálhatósága felülmúlhatatlan. Ráadásul szinte minden Linux, Unix és macOS rendszeren alapértelmezetten elérhetők, sőt, a Windows Subsystem for Linux (WSL) révén Windows alatt is. Ebben a cikkben három alapvető és rendkívül hasznos eszközt mutatunk be részletesen: a diff, a cmp és a comm parancsokat.

A Nagymester: diff (Difference)

A diff az egyik leggyakrabban használt és legsokoldalúbb parancssori eszköz a fájlok összehasonlítására. Két fájl közötti különbségeket sorról sorra vizsgálja, és egy jól értelmezhető formátumban jeleníti meg, amelyből egyértelméűen kiderül, mely sorok hiányoznak, melyek lettek hozzáadva, és melyek módosultak.

Alapok és kimenet értelmezése

A diff alapvető használata rendkívül egyszerű:

diff file1.txt file2.txt

A kimenet elsőre talán bonyolultnak tűnhet, de logikusan felépített. Nézzünk egy egyszerű példát:

file1.txt:
alma
körte
szilva
banán

file2.txt:
alma
körte
narancs
banán
eper

Futtassuk a diff file1.txt file2.txt parancsot:

3c3,4
< szilva
---
> narancs
> eper

Nézzük meg, mit jelentenek ezek a sorok:

  • 3c3,4: Ez az első sor a változás típusát és helyét írja le.
    • 3: A file1.txt fájl 3. soráról van szó.
    • c: A „c” a „change” (módosítás) rövidítése. Lehetne „a” (add – hozzáadás) vagy „d” (delete – törlés) is.
    • 3,4: A file2.txt fájl 3. és 4. soráról van szó.

    Ez tehát azt jelenti, hogy a file1.txt 3. sora megváltozott, és a file2.txt 3. és 4. sorává vált.

  • < szilva: Ez a sor a file1.txt-ből származik, és azt mutatja, mi van a file1.txt 3. sorában. A < jel azt jelzi, hogy ez a sor a bal oldali fájlból (az elsőként megadottból) hiányzik a jobb oldali fájlból.
  • ---: Ez egy elválasztó, ami a két fájl közötti határvonalat jelöli.
  • > narancs és > eper: Ezek a sorok a file2.txt-ből származnak, és azt mutatják, mi került a file2.txt 3. és 4. sorába. A > jel azt jelzi, hogy ezek a sorok a jobb oldali fájlban (a másodikként megadottban) vannak, és hiányoznak a bal oldali fájlból.

Gyakori és hasznos opciók

A diff parancs ereje az opcióiban rejlik:

  • -u vagy --unified (egységes kimenet): Ez a leggyakrabban használt és talán a legáttekinthetőbb kimeneti formátum, különösen fejlesztők körében. Ideális patch fájlok készítésére is.
    diff -u file1.txt file2.txt

    A kimenet így néz ki:

    --- file1.txt   2023-10-26 10:00:00.000000000 +0200
    +++ file2.txt   2023-10-26 10:01:00.000000000 +0200
    @@ -1,4 +1,5 @@
     alma
     körte
    -szilva
    +narancs
    +eper
     banán

    Magyarázat:

    • --- és +++ sorok: Ezek a fájlok neveit és időbélyegeit mutatják.
    • @@ -1,4 +1,5 @@: Ez az úgynevezett „hunk header” (blokk fejléc). A -1,4 azt jelenti, hogy a bal oldali fájlból (file1.txt) az 1. sortól kezdve 4 sorról van szó. A +1,5 azt jelenti, hogy a jobb oldali fájlban (file2.txt) az 1. sortól kezdve 5 sor van.
    • A sorok előtt lévő jelek:
      • (Nincs jel): Kontextus sorok – mindkét fájlban megegyeznek.
      • -: Ezek a sorok a bal oldali fájlban vannak, de a jobb oldaliban nincsenek (törölve lettek, vagy másra cserélődtek).
      • +: Ezek a sorok a jobb oldali fájlban vannak, de a bal oldaliban nincsenek (hozzá lettek adva).
  • -r vagy --recursive (rekurzív összehasonlítás): Könyvtárak tartalmának összehasonlítására szolgál, alkönyvtárakba is belépve.
    diff -r dir1 dir2
  • -N vagy --new-file: Amikor rekurzívan hasonlít össze könyvtárakat, ez az opció kezeli azokat a fájlokat, amelyek csak az egyik könyvtárban léteznek. Ezeket úgy kezeli, mintha a másik könyvtárban egy üres fájl lenne a helyükön.
  • -q vagy --brief: Csak azt jelzi, ha a fájlok különböznek, anélkül, hogy a részleteket kiírná. Gyors ellenőrzésre ideális.
    diff -q file1.txt file2.txt

    Kimenet (ha különböznek): Files file1.txt and file2.txt differ

  • -i vagy --ignore-case: Kis- és nagybetűk figyelmen kívül hagyása az összehasonlítás során.
  • -w vagy --ignore-all-space: Mindenféle szóköz változás (szám, pozíció) figyelmen kívül hagyása. Pl. a b és a b egyezőnek számít.
  • -b vagy --ignore-space-change: Csak a szóközök számában bekövetkező változások figyelmen kívül hagyása. Pl. a b és a b egyező, de ab és a b eltérő.
  • -y vagy --side-by-side: Oldalról-oldalra (két oszlopos) nézetben mutatja a különbségeket. Ehhez általában nagyobb terminálra van szükség.
    diff -y file1.txt file2.txt

    A sdiff parancs gyakorlatilag a diff -y aliasa, de további interaktív opciókat is kínálhat.

  • -x PATTERN vagy --exclude=PATTERN: Rekurzív könyvtár-összehasonlítás során kihagyja azokat a fájlokat vagy könyvtárakat, amelyek neve illeszkedik a megadott mintára (glob minta, pl. *.log).
  • -I REGEXP vagy --ignore-matching-lines=REGEXP: Azokat a sorokat hagyja figyelmen kívül, amelyek illeszkednek a megadott reguláris kifejezésre. Például diff -I '^#' config1.txt config2.txt kihagyja a kommenteket (amelyek # jellel kezdődnek).

A Bináris Összehasonlító: cmp (Compare)

Míg a diff a szöveges fájlok tartalmának sorról sorra történő elemzésére specializálódott, addig a cmp (compare) eszköz binárisan hasonlít össze fájlokat. Ennek fő előnye, hogy bármilyen típusú fájllal (szöveges, kép, futtatható program, archívum stb.) működik, és a legelső különbséget azonosítja bájtról bájtra.

Alapok és kimenet értelmezése

Az alapvető szintaxis hasonló a diff-hez:

cmp file1 file2

Ha a fájlok megegyeznek, a cmp nem ad ki semmilyen kimenetet, és a kilépési kódja (exit status) 0 lesz. Ez rendkívül hasznos szkriptekben, ahol csak arra van szükség, hogy tudjuk, van-e különbség.

echo $?  # Kiírja az előző parancs kilépési kódját

Ha a fájlok különböznek, a cmp kiírja az első eltérő bájt és sor számát. Például:

file1.txt:
apple
banana

file2.txt:
aple
banana

Futtassuk a cmp file1.txt file2.txt parancsot:

file1.txt file2.txt differ: byte 2, line 1

Ez azt jelenti, hogy az első különbséget a 2. bájton találta (az p helyett a file2.txt-ben l van), az 1. sorban.

Gyakori opciók

  • -s vagy --silent: Elnyomja a kimenetet, csak a kilépési kódot adja vissza. 0, ha a fájlok azonosak, 1, ha különböznek, 2 hiba esetén. Ideális szkripteléshez.
    cmp -s file1 file2 && echo "Azonos" || echo "Különböző"
  • -l vagy --verbose: Listázza az összes eltérést bájtról bájtra. Minden sorban az eltérő bájtok helyét (ofszet), és hexadecimális értékeit mutatja.
    cmp -l file1 file2

Mikor használd a cmp-t?
Akkor, ha pontos bináris egyezést keresel. Különösen hasznos futtatható programok, képek, archív fájlok (ZIP, TAR), vagy bármilyen nem szöveges tartalom összehasonlításakor, ahol a diff nem lenne hatékony, vagy félrevezető kimenetet adna. Gyorsan megmondja, ha két fájl bájtra pontosan azonos-e, ami például letöltött fájlok integritásának ellenőrzésére is alkalmas lehet.

A Közös Pontok Elemzője: comm (Common)

A comm parancs egy kicsit más célt szolgál. Két rendezett szöveges fájlt hasonlít össze, és három oszlopban jeleníti meg a kimenetet:

  1. Oszlop: Sorok, amelyek csak az első fájlban vannak benne.
  2. Oszlop: Sorok, amelyek csak a második fájlban vannak benne.
  3. Oszlop: Sorok, amelyek mindkét fájlban benne vannak.

Fontos megkötés, hogy a comm parancs csak rendezett fájlokkal működik korrektül! Ha a fájlok nincsenek rendezve, rendezze őket előbb a sort paranccsal, vagy irányítsa a kimenetüket a comm bemenetére.

Alapok és kimenet értelmezése

Tegyük fel, hogy van két rendezett fájlunk:

fileA.txt:
alma
banán
körte

fileB.txt:
banán
eper
körte

Futtassuk a comm fileA.txt fileB.txt parancsot:

alma
        eper
                banán
                körte

A kimenet magyarázata:

  • Az alma szó az első oszlopban van (az elején nincs tabulátor), mert csak a fileA.txt-ben található meg.
  • Az eper szó a második oszlopban van (egy tabulátor van az elején), mert csak a fileB.txt-ben található meg.
  • A banán és körte szavak a harmadik oszlopban vannak (két tabulátorral kezdődnek), mert mindkét fájlban benne vannak.

Gyakori opciók

A comm leggyakoribb opciói a kimeneti oszlopok elnyomására szolgálnak:

  • -1: Elnyomja az első oszlopot (azokat a sorokat, amelyek csak az 1. fájlban vannak).
  • -2: Elnyomja a második oszlopot (azokat a sorokat, amelyek csak a 2. fájlban vannak).
  • -3: Elnyomja a harmadik oszlopot (azokat a sorokat, amelyek mindkét fájlban benne vannak).

Ezek kombinációjával különböző „halmazműveleteket” végezhetünk:

  • Csak az 1. fájlban lévő sorok: comm -23 fileA.txt fileB.txt
  • Csak a 2. fájlban lévő sorok: comm -13 fileA.txt fileB.txt
  • Csak a mindkét fájlban lévő sorok (metszet): comm -12 fileA.txt fileB.txt

Mikor használd a comm-ot?
Akkor, ha rendezett lista-szerű fájlokkal dolgozol, és szeretnéd gyorsan látni a közös elemeket, vagy az egyik listában lévő elemeket, amelyek nincsenek a másikban. Például felhasználónevek listájának, vagy hálózati portok listájának összehasonlítására kiváló.

Speciális Eszközök és Tippek

sdiff

Ahogy fentebb említettük, az sdiff a diff -y egy kényelmesebb formája. Két fájlt hasonlít össze oldalról-oldalra nézetben, és interaktív módban is használható a különbségek azonnali szerkesztésére vagy egyesítésére. Mivel a diff képes erre a kimenetre, az sdiff ritkábban kerül elő önállóan, de érdemes tudni a létezéséről.

Fájlintegritás-ellenőrzés: md5sum és sha256sum

Bár nem közvetlenül fájltartalom-összehasonlító eszközök, az md5sum és sha256sum parancsok rendkívül hasznosak lehetnek a fájlok integritásának ellenőrzésére. Ezek a parancsok egy egyedi „ujjlenyomatot” (hash-t vagy ellenőrzőösszeget) generálnak a fájl tartalmából. Ha két fájl hash-e megegyezik, akkor gyakorlatilag biztos, hogy a tartalmuk is azonos. Ha a hash különbözik, akkor a fájlok eltérőek.

md5sum file1.txt
sha256sum file2.txt

Ez egy gyors módszer annak ellenőrzésére, hogy egy letöltött fájl nem sérült-e meg, vagy hogy két fájl tartalmát megváltoztatták-e.

Verziókezelő rendszerek és a diff

A modern verziókezelő rendszerek, mint a Git, belsőleg használják a diff funkcionalitást a változások nyomon követésére. A git diff parancs például a helyi módosításokat vagy két commit közötti különbségeket mutatja be, gyakran a unified diff formátumot használva. Ez is jól mutatja a diff parancs alapvető fontosságát a szoftverfejlesztésben.

Grafikus eszközök említése

Bár a cikk a parancssorra fókuszál, érdemes megemlíteni, hogy komplexebb, vizuális összehasonlításokra léteznek kiváló grafikus eszközök. A Meld, a KDiff3 vagy a Beyond Compare nagyszerűen kiegészítik a parancssori eszköztárat, különösen akkor, ha több fájlt, vagy bonyolult szerkezetű szövegeket kell összehasonlítani, esetleg interaktívan egyesíteni a változásokat.

Melyik Eszközt Mikor Használjuk?

A választás az Ön igényeitől és a fájlok típusától függ:

  • diff: A „mindenes” eszköz szöveges fájlok összehasonlítására. Ha tudni akarja, mely sorok változtak, mi lett hozzáadva vagy törölve, és szeretne patch fájlt generálni, akkor ez a nyerő választás. Képes könyvtárak rekurzív összehasonlítására is.
  • cmp: Ha arra van szüksége, hogy gyorsan és bájtról bájtra ellenőrizze, két fájl tartalmát pontosan azonos-e, függetlenül attól, hogy szöveges vagy bináris fájlokról van szó. Az első különbség helyét jelzi. Ideális integritás ellenőrzésre.
  • comm: Két rendezett szöveges lista (pl. felhasználónevek, IP-címek) halmazműveleteire (közös elemek, csak az egyikben lévők). Ne feledje: csak rendezett fájlokkal működik korrektül!
  • md5sum/sha256sum: Fájlok gyors integritás- vagy azonosság-ellenőrzésére hash-ek alapján. Nem mutatja meg a különbségeket, csak azt, hogy van-e.

Gyakorlati Tanácsok és Jógyakorlatok

  1. Mindig olvassa el a man oldalakat: Minden parancsnak (diff, cmp, comm) van egy „man page”-e (kézikönyv oldala). Használja a man diff parancsot a részletesebb információkért és az összes elérhető opció megismeréséhez.
  2. Kezdje egyszerűen: Ne terhelje túl magát az összes opcióval egyszerre. Kezdje az alapvető használattal, majd fokozatosan fedezze fel a haladóbb funkciókat, ahogy szüksége van rájuk.
  3. Automatizálás: A parancssori eszközök ereje az automatizálásban rejlik. Írjon shell szkripteket a fájlösszehasonlítások automatizálására, például konfigurációs fájlok változásainak nyomon követésére vagy adatellenőrzésre.
  4. Patch fájlok készítése és alkalmazása: A diff -u kimenete egy „patch” fájl, amelyet a patch paranccsal alkalmazhatunk. Ez rendkívül hasznos a kódváltozások megosztására anélkül, hogy az egész fájlt elküldenénk.
  5. Kimenet átirányítása: A parancsok kimenetét átirányíthatja egy fájlba (> output.txt) a későbbi elemzés vagy megőrzés céljából.

Összegzés

A fájlok tartalmának összehasonlítása kulcsfontosságú készség a modern digitális világban, legyen szó szoftverfejlesztésről, rendszerfelügyeletről, adatelemzésről vagy egyszerűen csak a személyes fájlok rendszerezéséről. A parancssori eszközök, mint a diff, cmp és comm, hihetetlenül hatékony, gyors és rugalmas megoldásokat kínálnak erre a feladatra. Bár elsőre ijesztőnek tűnhet a parancssor használata, a bennük rejlő erő és a precizitás, amivel dolgoznak, hamar elengedhetetlenné teszi őket az Ön eszköztárában. Gyakorlással és felfedezéssel Ön is igazi mesterévé válhat a fájlok összehasonlításának!

Leave a Reply

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük