Twee CSV-bestanden vergelijken en wijzigingen vinden

De snelste manier om twee CSV-bestanden te vergelijken is beide in een diff-tool naast elkaar te plakken, de kolommen uit te lijnen en de rijen te lezen die het tool markeert. Het vergelijken is het makkelijke deel. Het is de ruis waar mensen op stuklopen: een herschikte export, een puntkomma in plaats van een komma of een waarde die iemand tussen aanhalingstekens heeft gezet kunnen twee bestanden met dezelfde gegevens eruit laten zien alsof ze niets gemeen hebben.

Deze gids laat zien hoe je een schone, betrouwbare CSV-diff krijgt. We kijken naar waarom twee gelijkwaardige exports op papier uit elkaar lopen, welke methoden de moeite waard zijn om te kennen, en een uitgewerkt voorbeeld dat je kunt volgen. Wil je alleen het tool, dan doet onze CSV-vergelijkpagina dit in de browser.

Waarom CSV-bestanden bedrieglijk lastig te vergelijken zijn

CSV ziet er eenvoudig uit, maar heeft geen enkele strikte standaard. Het dichtstbijzijnde is RFC 4180, en veel echte bestanden volgen dat niet. Twee exports van dezelfde tabel kunnen verschillen in scheidingsteken, aanhalingstekens, regeleindes en rijvolgorde terwijl ze precies dezelfde gegevens beschrijven. Een gewone tekst-diff weet daar niets van en markeert dus alles.

Dit is het belangrijkste om voor je begint te beslissen: maakt de rijvolgorde voor jou uit? Een database-export gesorteerd op naam en dezelfde export gesorteerd op ID bevatten exact dezelfde set records, maar een regel-diff kleurt bijna elke rij rood en groen. Als de rijen een stabiele sleutel hebben (een ID-kolom), maakt het eerst sorteren van beide bestanden op die sleutel de diff weer leesbaar.

Lijkt op een wijziging, is het meestal niet
Wat je in de diff zietIs het een echte wijziging?Wat te doen
Rijen in een andere volgordeNee, als de gegevens dezelfde set zijnBeide bestanden sorteren op een sleutelkolom
Komma vs. puntkomma als scheidingstekenNee, dezelfde veldenNaar één scheidingsteken normaliseren
Ada vs. "Ada"Nee, aanhalingstekens zijn hier optioneelAanhalingstekens normaliseren
CRLF- vs. LF-regeleindesNeeRegeleindes normaliseren
Een lege regel aan het eindNeeVerwijderen
Een celwaarde is veranderdJaOnderzoeken, dit is echt

De scheidingsteken-rij betrapt veel mensen, vooral over regio's heen: veel Europese locales gebruiken een puntkomma omdat de komma het decimaalteken is. Dezelfde gegevens, ander scheidingsteken. Wil je het detail over hoe browsers en tools tabulaire tekst lezen, dan is de MDN-notitie over bestanden lezen in de browser een handig startpunt.

Vier manieren om CSV te vergelijken en wanneer je welke pakt

Er is geen enkele beste methode. Het hangt af van de grootte van de bestanden en of de rijvolgorde uitmaakt. Zo verhouden de gangbare opties zich.

MethodeHet best voorMoeiteBegrijpt CSV?
Met het blote oogPiepkleine bestanden, een handvol rijenLaagNee, jij bent de parser
Online diff-toolSnelle controles, plakken vanuit overalLaagRegel voor regel, ja
Spreadsheet-appVisuele review, formules, filterenGemiddeldJa, maar handmatig
Opdrachtregel (sort, csvkit)Grote bestanden, scripting, vergelijkingen op sleutelGemiddeldJa, als je eerst sorteert

Voor de meeste mensen wint een browsertool op snelheid: niets te installeren, en je kunt een export direct uit een download of een databaseclient plakken. De adder onder het gras is de ruis door rijvolgorde en scheidingsteken, die we hierna behandelen. Voor heel grote bestanden is csvkit op de opdrachtregel het leren waard.

De snelste schone vergelijking, stap voor stap

Dit is de routine die ik gebruik wanneer iemand me twee exports geeft en vraagt: "wat is er anders?". Het kost minder dan een minuut.

  1. Zorg dat beide bestanden hetzelfde scheidingsteken en dezelfde kopregel hebben.
  2. Als de rijvolgorde niet uitmaakt, sorteer beide bestanden dan eerst op een sleutelkolom.
  3. Open de CSV-vergelijktool.
  4. Plak het origineel links en de nieuwe versie rechts.
  5. Lees het resultaat. Groen is een toegevoegde rij, rood is een verwijderde rij, en een gewijzigde cel verschijnt als één van elk.

Stap twee is de hele truc wanneer de rijen ongeordend zijn. Zodra beide bestanden op dezelfde manier gesorteerd zijn, blijft alleen nog over om de rijen te markeren die echt veranderd zijn. Onze diff-engine is gebouwd op Google's diff-match-patch, die eerst regel voor regel vergelijkt en zo ook bij lange bestanden snel blijft.

Een uitgewerkt voorbeeld

Stel dat je een wijziging in een gebruikerstabel beoordeelt. Hier is het voor:

id,name,role,seats
7,Ada Lovelace,editor,3
8,Alan Turing,viewer,1

En hier is het na, geëxporteerd in een andere rijvolgorde:

id,name,role,seats
8,Alan Turing,viewer,1
7,Ada Lovelace,admin,5

Gooi die in een kale regel-diff en beide datarijen lijken veranderd, omdat ze van plaats zijn gewisseld. Sorteer beide op de kolom id, en het echte verhaal is kort:

Wat er werkelijk veranderd is
Rij (op id)KolomVoorNaWijziging
7roleeditoradminGewijzigd
7seats35Gewijzigd
8Geen wijziging (alleen verplaatst)

Eén echte bewerking: Ada's rol en aantal stoelen zijn veranderd. Alans rij is alleen verplaatst. Die promotie van editor naar admin is precies het soort ding dat je bij een review wilt opmerken, en het is makkelijk te missen wanneer het begraven ligt onder rijen die de diff ten onrechte als gewijzigd markeerde.

De rijvolgorde-ruis wegwerken op de opdrachtregel

Als je bestanden al op schijf staan en de rijen geen inherente volgorde hebben, werkt hetzelfde "eerst sorteren"-idee met twee korte commando's. Houd de kopregel op zijn plaats en sorteer de rest:

(head -1 old.csv; tail -n +2 old.csv | sort) > old.sorted.csv
(head -1 new.csv; tail -n +2 new.csv | sort) > new.sorted.csv
diff old.sorted.csv new.sorted.csv

Nu meldt diff alleen rijen die echt veranderd zijn, omdat beide bestanden in dezelfde volgorde staan. Voor vergelijkingen op sleutel die ook de kolomvolgorde negeren, geven csvsort en csvjoin van csvkit je meer controle. Dit is het terminal-equivalent van beide kanten sorteren voordat je in de browser vergelijkt.

Scheidingstekens, aanhalingstekens en de rommelige realiteit

Echte CSV-bestanden breken voortdurend de regels. Een veld dat een komma bevat moet tussen aanhalingstekens, dus "Lovelace, Ada" is één veld, niet twee. Aanhalingstekens binnen een veld tussen aanhalingstekens worden verdubbeld: "Ze zei ""hoi""". En het scheidingsteken zelf varieert: spreadsheets in locales met een decimale komma exporteren met puntkomma's, en tab-gescheiden bestanden (TSV) zijn gangbaar in datapijplijnen. Zorg vóór het vergelijken dat beide bestanden hetzelfde scheidingsteken en dezelfde aanhalingsteken-conventie gebruiken, of normaliseer ze met een parser die RFC 4180 volgt. Anders vergelijkt de diff twee verschillende dialecten, niet twee versies van dezelfde gegevens.

Veelvoorkomende valkuilen om op te letten

ValkuilWaarom het bijtOplossing
Niet-overeenkomende scheidingstekensKomma vs. puntkomma laat elk veld anders lijkenEerst naar één scheidingsteken normaliseren
BOM aan het beginEen verborgen byte-order mark verandert de eerste kopcelDe BOM verwijderen voor het vergelijken
ID's met voorloopnullenEen spreadsheet heeft 007 mogelijk in 7 veranderdID-kolommen als tekst bewaren; als strings vergelijken
Ingebedde regeleindesEen veld tussen aanhalingstekens kan een regeleinde bevatten en elke volgende rij verschuivenEen echte CSV-parser gebruiken, geen regelsplitsing
Spaties aan het eind van cellenOnzichtbare spaties verschijnen als een wijzigingCelwaarden trimmen voor het vergelijken

Wanneer een spreadsheet de betere tool is

Een tekst-diff is perfect om te zien welke rijen zijn veranderd en de wijziging als gegevens te beoordelen. Maar als je over duizenden rijen moet filteren, pivotteren of per formule vergelijken, past een spreadsheet beter: importeer beide bestanden, lijn ze uit op sleutel en gebruik een opzoekfunctie om afwijkingen te markeren. De twee benaderingen vullen elkaar aan. Gebruik de diff voor een snelle visuele blik en de spreadsheet wanneer je de gegevens moet versnijden. Voor de regels van het onderliggende formaat in beide gevallen is het CSV-overzicht van Wikipedia een degelijke referentie.

Gerelateerde tools

CSV is zelden het enige formaat waarmee je werkt. Als dezelfde gegevens ook als JSON bestaan, past JSON-vergelijken hetzelfde idee toe. Duplicaten uit een kolom met waarden verwijderen gaat snel met dubbele regels verwijderen, en rijen vóór een diff in een voorspelbare volgorde zetten is precies waarvoor regels sorteren bedoeld is.

Veelgestelde vragen

Worden CSV-bestanden bij online vergelijken ergens geüpload?
Op comparetext.org draait de diff in je browser. De twee CSV-bestanden worden door JavaScript op je eigen machine vergeleken, dus er wordt niets naar een server gestuurd tenzij je expliciet op Opslaan of Delen klikt. Dat maakt het veilig voor klantexports, financiële gegevens en andere spreadsheets die je niet zou willen plakken op een site die bij elke toetsaanslag uploadt.
Waarom tonen mijn twee CSV-bestanden elke rij als verschillend?
Bijna altijd is het de rijvolgorde of het scheidingsteken, geen echte wijzigingen. De ene export is anders gesorteerd dan de andere, of de ene gebruikt komma's en de andere puntkomma's, of de regeleindes verschillen. Zorg dat beide bestanden hetzelfde scheidingsteken gebruiken en sorteer ze dan op een sleutelkolom zodat de volgorde niet meer uitmaakt. Daarna krimpt de diff meestal tot het handjevol rijen en cellen dat echt veranderd is.
Hoe vergelijk ik twee CSV-bestanden terwijl ik de rijvolgorde negeer?
Sorteer beide bestanden op een stabiele sleutelkolom voordat je vergelijkt. Als de rijen een ID hebben, sorteer daarop; anders sorteer je de hele rij. Houd de kopregel op zijn plaats en sorteer alleen de datarijen. In de browser kun je de gesorteerde versies plakken; op de opdrachtregel sorteer je het bestand na de kopregel. Zodra beide bestanden in dezelfde volgorde staan, verschijnen alleen de rijen die echt veranderd zijn in de diff, in plaats van elke rij die simpelweg verplaatst is.
Waarom gebruikt mijn CSV puntkomma's in plaats van komma's?
Veel Europese locales gebruiken de komma als decimaalteken, dus spreadsheet-apps exporteren CSV met een puntkomma als scheidingsteken om dubbelzinnigheid te vermijden. De gegevens zijn hetzelfde; alleen het scheidingsteken verschilt. Zorg vóór het vergelijken van twee bestanden dat ze hetzelfde scheidingsteken gebruiken, anders zie je elk veld als gewijzigd gemarkeerd. Beide naar komma's (of beide naar puntkomma's) normaliseren met een CSV-bewuste tool lost het op. Tab-gescheiden bestanden hebben hetzelfde probleem met een ander scheidingsteken.
Hoe vergelijk ik CSV-bestanden met een andere kolomvolgorde?
Een gewone tekst-diff vergelijkt rijen van links naar rechts, dus herschikte kolommen lijken een totale wijziging zelfs als de gegevens overeenkomen. Om dit aan te pakken, herschik je eerst de kolommen zodat ze in beide bestanden overeenkomen, of gebruik je een CSV-bewuste tool die op kopnaam vergelijkt in plaats van op positie. Opdrachtregeltools als csvkit kunnen kolommen op naam selecteren en herschikken. Zodra de kolommen in dezelfde volgorde staan, werkt een normale rij-voor-rij-diff weer.
Kan ik grote CSV-bestanden vergelijken zonder dat de pagina vastloopt?
Ja, tot op zekere hoogte. Een diff in regelmodus blijft snel bij bestanden met duizenden rijen omdat hij eerst hele regels vergelijkt in plaats van elk teken. Heel grote bestanden (tientallen megabytes of miljoenen rijen) kun je beter aanpakken met een opdrachtregeltool als csvkit of een database-import, die de gegevens streamen. Voor een export waar je comfortabel doorheen kunt scrollen in een browser is een online diff de snellere optie.

Klaar om het te proberen? Plak je bestanden in de CSV-vergelijktool en zie wat er veranderd is.