Twee JSON-bestanden vergelijken en wijzigingen vinden
De snelste manier om twee JSON-bestanden te vergelijken is beide in een naast-elkaar-diff-tool te plakken, ze op dezelfde manier te formatteren en de gemarkeerde regels te lezen. Het moeilijke deel is meestal niet het vergelijken zelf. Het is het ruis: opnieuw geordende sleutels, verschillende inspringing en losse afsluitende komma's kunnen ervoor zorgen dat twee bijna identieke bestanden lijken niets gemeen te hebben.
Deze gids legt uit hoe u een schone, betrouwbare diff krijgt. We kijken naar waarom JSON-bestanden op papier uit elkaar drijven terwijl ze inhoudelijk hetzelfde blijven, de handvol methoden die het waard zijn te kennen, en een uitgewerkt voorbeeld dat u kunt volgen. Als u gewoon de tool wilt, doet onze JSON-vergelijkingspagina dit alles in de browser.
Waarom JSON-bestanden bedrieglijk moeilijk te vergelijken zijn
JSON heeft een kleine, strikte grammatica (zie de specificatie op json.org), maar geeft schrijvers veel vrijheid in hoe ze tekst opmaken. Twee bestanden kunnen hetzelfde object beschrijven en toch byte voor byte verschillen. Een gewone tekstdiff weet daar niets van, dus markeert het alles nauwgezet.
Dit is het belangrijkste om te internaliseren voordat u begint:
objectsleutels in JSON hebben geen volgorde. De specificatie
(RFC 8259)
definieert een object als een ongeordende verzameling naam/waarde-paren.
Dus {"name":"Ada","id":7} en
{"id":7,"name":"Ada"}
zijn gelijk, ook al kleurt een regeldiff ze rood en groen.
| Wat u in de diff ziet | Is het een echte wijziging? | Wat te doen |
|---|---|---|
| Sleutels in een andere volgorde | Nee, objecten zijn ongeordend | Sleutels aan beide kanten sorteren |
| 2-spatie vs. 4-spatie inspringing | Nee | Beide kanten hetzelfde formatteren |
| Geminimaliseerd vs. opgemaak | Nee | Beide kanten formatteren |
| Afsluitende nieuwe regel aan het einde van het bestand | Nee | Negeren of witruimte verwijderen |
Een waarde veranderde van "7" naar 7 | Ja, string vs. getal | Onderzoeken, dit is echt |
| Array-items in een andere volgorde | Misschien, arrays zijn geordend | Beslissen of volgorde hier belangrijk is |
Die laatste rij verrast mensen. Arrays behouden hun volgorde, objecten
niet. Dus [1, 2, 3] en [3, 2, 1] zijn echt
verschillend, maar de sleutels binnen een object kunnen vrij worden
herschikt. Als u de technische details wilt weten over hoe JavaScript dit
alles parseert, heeft MDN een solide
referentie over het JSON-object.
Vier manieren om JSON te vergelijken en wanneer u ze gebruikt
Er is geen enkele beste methode. Het hangt ervan af waar de bestanden staan en wat u wilt weten. Zo vergelijken de gangbare opties.
| Methode | Het beste voor | Inspanning | Begrijpt JSON? |
|---|---|---|---|
| Handmatig doorkijken | Kleine bestanden, één of twee velden | Laag | Nee, u bent de parser |
| Online diff-tool | Snelle controles, plakken van overal | Laag | Met opmaak + sleutels sorteren, ja |
Opdrachtregel (jq, diff) | Bestanden op schijf, scripting, grote bestanden | Gemiddeld | Ja, als u eerst sorteert |
IDE of git diff | Bestanden al in een repository | Laag als gecommit | Standaard regelgebaseerd |
Voor de meeste mensen wint een browsertool op snelheid omdat er niets geïnstalleerd hoeft te worden en u een fragment direct vanuit een logboek of een API-aanroep kunt plakken. Het nadeel is opmaakruis, waar we hierna mee omgaan. Als u veel in de terminal werkt, is jq de tool om te leren, en we laten de ene vlag zien die ertoe doet.
De snelste schone vergelijking, stap voor stap
Dit is de routine die ik gebruik wanneer iemand me twee configuratiebestanden geeft en vraagt "wat is er anders?" Het duurt ongeveer vijftien seconden.
- Open de JSON-vergelijkingstool.
- Plak het origineel links, de nieuwe versie rechts.
- Klik op Formatteren aan beide kanten zodat ze dezelfde inspringing delen.
- Zet sleutels sorteren (canonicaliseren) aan zodat opnieuw geordende sleutels niet meer als wijzigingen verschijnen.
- Lees het resultaat. Groen is toegevoegd, rood is verwijderd, en een gewijzigde waarde verschijnt als één van elk.
Stap drie en vier zijn de hele truc. Zodra beide bestanden identiek zijn opgemaakt en hun sleutels gesorteerd zijn, is het enige dat overblijft om te markeren wat er echt is veranderd. Onze diff-engine is gebouwd op Google's diff-match-patch, dat eerst regel voor regel vergelijkt zodat het snel blijft, zelfs bij lange bestanden.
Een uitgewerkt voorbeeld
Stel dat u een wijziging in een gebruikersrecord beoordeelt. Dit is de situatie van vóór:
{
"name": "Ada Lovelace",
"role": "editor",
"active": true,
"seats": 3
}
En dit is de situatie erna, zoals een teamgenoot het aanleverde:
{
"active": true,
"name": "Ada Lovelace",
"role": "admin",
"seats": 5,
"team": "platform"
}
Gooit u die in een gewone regeldiff, dan lijkt het alsof bijna elke regel is verschoven, omdat de sleutels in een andere volgorde staan. Formatteer en sorteer beide, en het echte verhaal is kort:
| Veld | Voor | Na | Wijziging |
|---|---|---|---|
role | editor | admin | Gewijzigd |
seats | 3 | 5 | Gewijzigd |
team | — | platform | Toegevoegd |
name | Ada Lovelace | Ada Lovelace | Geen wijziging |
active | true | true | Geen wijziging (alleen verplaatst) |
Drie echte bewerkingen: een rolverhoging, een plaatsenaantal en een nieuw
teamveld. De herordening was ruis. Die bevordering van editor
naar admin is precies het soort ding dat u wilt opvangen bij
de beoordeling, en het is gemakkelijk te missen wanneer het begraven ligt
onder twintig regels valse positieven.
Opmaakruis op de opdrachtregel elimineren
Als uw bestanden al op schijf staan, werkt hetzelfde idee van "formatteren
en sorteren" met twee korte opdrachten. De vlag -S vertelt jq
om objectsleutels te sorteren; er doorheen pipen normaliseert beide
bestanden zodat een gewone diff eerlijk is:
jq -S . old.json > old.sorted.json
jq -S . new.json > new.sorted.json
diff old.sorted.json new.sorted.json
Nu rapporteert diff alleen waarden die echt zijn veranderd,
omdat beide bestanden dezelfde inspringing en dezelfde sleutelvolgorde
hebben. Dit is het terminale equivalent van klikken op Formatteren en
sleutels sorteren in de browser.
Tekstdiff vs. structurele diff
Al het bovenstaande is een tekstdiff: snel, visueel en perfect
voor een mens die een wijziging leest. Een structurele diff gaat
verder en beschrijft de wijziging als data. De standaard daarvoor is JSON
Patch, gedefinieerd in
RFC 6902,
dat bewerkingen uitdrukt als operaties zoals replace en
add op een bepaald pad. U wilt een structurele diff wanneer
een programma de wijziging moet toepassen, niet alleen een persoon die
ernaar kijkt. Voor dagelijkse beoordeling is een tekstdiff met gesorteerde
sleutels meer dan voldoende.
Veelvoorkomende valkuilen om op te letten
| Valkuil | Waarom het toeslaat | Oplossing |
|---|---|---|
| Getalnauwkeurigheid | Gehele getallen boven 2^53 − 1 verliezen nauwkeurigheid in JavaScript | Vergelijk grote ID's als strings; zie MAX_SAFE_INTEGER |
| Unicode-escapes | "café" en "café" zijn dezelfde string, verschillende bytes | Formatteer beide kanten, wat de codering normaliseert |
| Dubbele sleutels | De meeste parsers bewaren de laatste stilletjes | Valideer de JSON voordat u de diff vertrouwt |
| Afsluitende komma's | Geen geldige JSON; één bestand kan mogelijk helemaal niet worden geparseerd | Herstel eerst de syntaxis, de validator markeert het |
| String vs. getal | "5" en 5 zien er vergelijkbaar uit maar zijn verschillende typen | Dit is een echte wijziging, negeer het niet |
Gerelateerde tools
JSON is zelden het enige formaat waarmee u te maken heeft. Als u configuraties tussen omgevingen vergelijkt, past YAML-vergelijking hetzelfde idee toe op YAML. Wijzigingen tussen twee API-aanroepen bekijken is precies waarvoor de API-respons diff is gebouwd, en afhankelijkheidsupdates zijn het gemakkelijkst te lezen op de pagina package.json diff.
Veelgestelde vragen
- Worden JSON-bestanden online ergens geüpload bij het vergelijken?
- Op comparetext.org wordt de diff in uw browser uitgevoerd. De twee JSON-bestanden worden vergeleken door JavaScript op uw eigen machine, zodat er niets naar een server wordt verzonden tenzij u expliciet op Opslaan of Delen klikt. Dat maakt het veilig voor configuratiebestanden, API-antwoorden en andere gegevens die u niet wilt plakken in een willekeurige website die bij elke toetsaanslag uploadt.
- Waarom tonen mijn twee JSON-bestanden elke regel als anders?
- Bijna altijd is het opmaak, niet echte wijzigingen. Het ene bestand is geminimaliseerd of ingesprongen met tabs, het andere met twee spaties, of de objectsleutels staan in een andere volgorde. Klik op Formatteren aan beide kanten zodat ze dezelfde inspringing gebruiken, sorteer dan de sleutels zodat volgorde er niet meer toe doet. Daarna krimpt de diff meestal tot de handvol waarden die echt zijn veranderd.
- Hoe vergelijk ik JSON terwijl ik de sleutelvolgorde negeer?
- JSON-objectsleutels hebben geen gedefinieerde volgorde, dus
{"a":1,"b":2}en{"b":2,"a":1}zijn gelijk. Om een tekstdiff te laten overeenstemmen, sorteert u de sleutels aan beide kanten voor het vergelijken. In de browser gebruikt u de canonicaliseer-optie (sleutels sorteren). Op de opdrachtregel doet jq dit:jq -S . file.json. Zodra beide bestanden sleutels in dezelfde gesorteerde volgorde hebben, verschijnen alleen echte waardewijzigingen. - Kan ik grote JSON-bestanden vergelijken zonder dat de pagina vastloopt?
- Ja, tot op zekere hoogte. Een regelmodus-diff blijft snel op bestanden met duizenden regels omdat het eerst hele regels vergelijkt in plaats van elk teken afzonderlijk. Zeer grote bestanden (meerdere megabytes) worden beter afgehandeld met een opdrachtregeltool zoals jq of git diff, die de gegevens streamt. Voor alles wat u comfortabel in een browser kunt doorscrollenm is een online diff de snellere optie.
- Wat is het verschil tussen een tekstdiff en een structurele diff van JSON?
- Een tekstdiff vergelijkt de bestanden regel voor regel, op dezelfde manier als het twee essays zou vergelijken. Een structurele diff begrijpt JSON, dus weet het dat een opnieuw geordende sleutel geen wijziging is en dat een verplaatste waarde binnen een array een verplaatsing is, niet een verwijdering plus een toevoeging. Tekstdiffs zijn sneller en goed genoeg voor de meeste beoordelingen. Structurele diffs (bijvoorbeeld JSON Patch per RFC 6902) zijn van belang wanneer u een wijziging moet beschrijven als data die een programma kan toepassen.
- Hoe vergelijk ik twee API-antwoorden?
- Sla elk antwoord op in een bestand of kopieer het uit het netwerktabblad van uw browser, plak dan het oude antwoord links en het nieuwe rechts. Formatteer beide zodat de inspringing overeenkomt, en sorteer sleutels als de API ze niet in een stabiele volgorde retourneert. De api-response-diff-tool is precies hierop afgestemd: een hernoemd veld, een gewijzigde statuscode of een waarde die tussen twee aanroepen van een string naar een getal is veranderd, opsporen.
Klaar om het uit te proberen? Plak uw bestanden in de JSON-vergelijkingstool en zie wat er is veranderd.