Hur man jämför två JSON-filer och hittar vad som har ändrats
Det snabbaste sättet att jämföra två JSON-filer är att klistra in båda i ett diff-verktyg med sida-vid-sida-vy, formatera dem på samma sätt och läsa raderna det markerar. Den svåra delen är vanligtvis inte jämförelsen. Det är bruset: omordnade nycklar, olika indragningar och löst hängande avslutande kommatecken kan få två nästan identiska filer att se ut som om de inte delar något alls.
Den här guiden går igenom hur man får en ren och tillförlitlig diff. Vi tittar på varför JSON-filer driftar ifrån varandra på pappret medan de förblir likadana i betydelse, de få metoder som är värda att känna till, och ett genomarbetat exempel du kan följa med i. Om du bara vill ha verktyget gör vår JSON-jämförelsesida allt detta i webbläsaren.
Varför JSON-filer är bedrägligt svåra att jämföra
JSON har en liten, strikt grammatik (se specifikationen på json.org), men ger skribenter stor frihet i hur de lägger upp texten. Två filer kan beskriva exakt samma objekt och ändå skilja sig byte för byte. En vanlig textdiff vet inget av detta, så den flaggar troget allt.
Det här är något att ta till sig innan du börjar: objektnycklar i JSON
har ingen ordning. Specifikationen
(RFC 8259)
definierar ett objekt som en oordnad mängd namn/värde-par. Så
{"name":"Ada","id":7} och {"id":7,"name":"Ada"}
är lika, även om en raddiff målar dem röda och gröna.
| Vad du ser i diff:en | Är det en verklig förändring? | Vad du ska göra |
|---|---|---|
| Nycklar i annan ordning | Nej, objekt är oordnade | Sortera nycklar på båda sidor |
| 2-mellanslag vs 4-mellanslag indragning | Nej | Formatera båda sidor likadant |
| Minifierad vs snyggt utskriven | Nej | Formatera båda sidor |
| Avslutande radbrytning i slutet av filen | Nej | Ignorera, eller trimma blanksteg |
Ett värde ändrat från "7" till 7 | Ja, sträng vs nummer | Undersök, detta är verkligt |
| Arrayelement i annan ordning | Kanske, arrayer är ordnade | Bestäm om ordningen spelar roll här |
Den sista raden överraskar folk. Arrayer behåller sin ordning, objekt gör
det inte. Så [1, 2, 3] och [3, 2, 1] är genuint
olika, men nycklarna inuti ett objekt kan blandas fritt. Om du vill ha
de tekniska detaljerna om hur JavaScript parsar allt detta har MDN en
solid
referens om JSON-objektet.
Fyra sätt att jämföra JSON, och när man ska använda vilket
Det finns ingen enda bästa metod. Det beror på var filerna finns och vad du försöker ta reda på. Så här ställer sig de vanliga alternativen mot varandra.
| Metod | Bäst för | Ansträngning | Förstår JSON? |
|---|---|---|---|
| Ögna igenom | Små filer, ett eller två fält | Låg | Nej, du är parsern |
| Online diff-verktyg | Snabba kontroller, klistra in varifrån som helst | Låg | Med format + sortera nycklar, ja |
Kommandorad (jq, diff) | Filer på disk, skriptning, stora filer | Medel | Ja, när du sorterar först |
IDE eller git diff | Filer redan i ett repo | Låg om committade | Radbaserad som standard |
För de flesta vinner ett webbläsarverktyg på hastighet eftersom det inte finns något att installera och du kan klistra in ett utdrag direkt från en logg eller ett API-anrop. Nackdelen är formateringsbrus, vilket vi tar itu med härnäst. Om du lever i terminalen är jq verktyget att lära sig, och vi visar den enda flaggan som spelar roll.
Den snabbaste rena jämförelsen, steg för steg
Det här är rutinen jag använder när någon räcker mig två konfigurationsfiler och frågar "vad är annorlunda?". Det tar ungefär femton sekunder.
- Öppna JSON-jämförelseverktyget.
- Klistra in originalet till vänster, den nya versionen till höger.
- Klicka på Formatera på båda sidor så att de delar samma indragning.
- Slå på sortera nycklar (kanonisera) så att omordnade nycklar slutar visas som ändringar.
- Läs resultatet. Grönt är tillagt, rött är borttaget, och ett ändrat värde visas som ett av vardera.
Steg tre och fyra är hela tricket. När båda filerna är identiskt formaterade och deras nycklar är sorterade är det enda kvar att markera det som faktiskt ändrades. Vår diff-motor är byggd på Googles diff-match-patch, som jämför rad för rad först så att den förblir snabb även på långa filer.
Ett genomarbetat exempel
Säg att du granskar en ändring i en användarpost. Här är tillståndet före:
{
"name": "Ada Lovelace",
"role": "editor",
"active": true,
"seats": 3
}
Och här är tillståndet efter, som en lagkamrat lämnade över det till dig:
{
"active": true,
"name": "Ada Lovelace",
"role": "admin",
"seats": 5,
"team": "platform"
}
Lägg in dem i en rå raddiff och det ser ut som om nästan varje rad har flyttats, eftersom nycklarna är i en annan ordning. Formatera och sortera båda, och den verkliga historien är kort:
| Fält | Före | Efter | Förändring |
|---|---|---|---|
role | editor | admin | Ändrad |
seats | 3 | 5 | Ändrad |
team | — | platform | Tillagd |
name | Ada Lovelace | Ada Lovelace | Ingen ändring |
active | true | true | Ingen ändring (bara omflyttad) |
Tre verkliga redigeringar: en rollhöjning, ett platsantal och ett nytt
teamfält. Omordningen var brus. Den befordringen från editor
till admin är precis den sorts sak du vill fånga i en
granskning, och den är lätt att missa när den är begravd under tjugo
rader falska positiver.
Eliminera formateringsbrus på kommandoraden
Om dina filer redan finns på disk fungerar samma idé med "formatera och
sortera" med två korta kommandon. Flaggan -S talar om för jq
att sortera objektnycklar; att röra båda filerna genom det normaliserar
dem så att en vanlig diff är ärlig:
jq -S . old.json > old.sorted.json
jq -S . new.json > new.sorted.json
diff old.sorted.json new.sorted.json
Nu rapporterar diff bara värden som verkligen har ändrats,
eftersom båda filerna har samma indragning och samma nyckelordning. Det
här är terminalmotsvarigheten till att klicka på Formatera och sortera
nycklar i webbläsaren.
Textdiff vs strukturell diff
Allt ovan är en textdiff: snabb, visuell och perfekt för en
människa som läser en ändring. En strukturell diff går längre
och beskriver ändringen som data. Standarden för det är JSON Patch,
definierad i
RFC 6902,
som uttrycker redigeringar som operationer som replace och
add vid en given sökväg. Du vill ha en strukturell diff när
ett program behöver tillämpa ändringen, inte bara en person som öga för
det. För daglig granskning räcker en textdiff med sorterade nycklar gott.
Vanliga fallgropar att hålla utkik efter
| Fallgrop | Varför den biter | Åtgärd |
|---|---|---|
| Nummerprecision | Heltal över 2^53 − 1 tappar precision i JavaScript | Jämför stora ID:n som strängar; se MAX_SAFE_INTEGER |
| Unicode-escape | "café" och "café" är samma sträng, olika bytes | Formatera båda sidor, vilket normaliserar kodningen |
| Dubbletter av nycklar | De flesta parsers behåller tyst den sista | Validera JSON:en innan du litar på diff:en |
| Avslutande kommatecken | Inte giltig JSON; en fil kanske inte ens kan parsas | Fixa syntaxen först, validatorn flaggar det |
| Sträng vs nummer | "5" och 5 ser lika ut men är olika typer | Det här är en verklig förändring, ignorera den inte |
Relaterade verktyg
JSON är sällan det enda formatet du har att göra med. Om du jämför konfiguration mellan miljöer tillämpar YAML-jämförelse samma idé på YAML. Att granska ändringar mellan två API-anrop är vad API-responsdiff-verktyget är byggt för, och beroendebumpar är enklast att läsa på package.json diff-sidan.
Vanliga frågor
- Laddar jämförelse av JSON-filer online upp dem någonstans?
- På comparetext.org körs diff:en i din webbläsare. De två JSON-filerna jämförs av JavaScript på din egen dator, så inget skickas till en server om du inte uttryckligen klickar på Spara eller Dela. Det gör det säkert för konfigurationsfiler, API-svar och annan data du inte skulle vilja klistra in på en slumpmässig webbplats som laddar upp vid varje knapptryckning.
- Varför visar mina två JSON-filer varje rad som annorlunda?
- Nästan alltid är det formatering, inte verkliga ändringar. En fil är minifierad eller indragen med tabbar, den andra med två mellanslag, eller objektnycklarna är i en annan ordning. Klicka på Formatera på båda sidor så att de använder samma indragning, sortera sedan nycklarna så att ordning slutar spela roll. Därefter krymper diff:en vanligtvis till det fåtal värden som genuint har ändrats.
- Hur jämför jag JSON med ignorerad nyckelordning?
- JSON-objektnycklar har ingen definierad ordning, så
{"a":1,"b":2}och{"b":2,"a":1}är lika. För att få en textdiff att hålla med, sortera nycklarna på båda sidor innan jämförelse. I webbläsaren, använd alternativet kanonisera (sortera nycklar). På kommandoraden gör jq det:jq -S . file.json. När båda filerna har nycklar i samma sorterade ordning dyker bara verkliga värdeändringar upp. - Kan jag jämföra stora JSON-filer utan att sidan fryser?
- Ja, upp till en punkt. En raddiff förblir snabb på filer med tusentals rader eftersom den jämför hela rader först istället för varje tecken. Mycket stora filer (flera megabyte) hanteras bättre med ett kommandoradsverktyg som jq eller git diff, som strömmar datan. För allt du bekvämt kan scrolla igenom i en webbläsare är en online-diff det snabbare alternativet.
- Vad är skillnaden mellan en textdiff och en strukturell diff av JSON?
- En textdiff jämför filerna rad för rad, på samma sätt som den skulle jämföra två uppsatser. En strukturell diff förstår JSON, så den vet att en omordnad nyckel inte är en förändring och att ett värde som har flyttats inuti en array är en flytt, inte en borttagning plus ett tillägg. Textdiff:ar är snabbare och tillräckligt bra för de flesta granskningar. Strukturella diff:ar (till exempel JSON Patch per RFC 6902) spelar roll när du behöver beskriva en förändring som data ett program kan tillämpa.
- Hur jämför jag två API-svar?
- Spara varje svar till en fil eller kopiera det från fliken nätverk i din webbläsare, klistra sedan in det gamla svaret till vänster och det nya till höger. Formatera båda så att indragning stämmer, och sortera nycklar om API:et inte returnerar dem i en stabil ordning. Verktyget api-response-diff är finjusterat för exakt detta: att hitta ett omdöpt fält, en ändrad statuskod, eller ett värde som flippade från en sträng till ett nummer mellan två anrop.
Vill du prova? Klistra in dina filer i JSON-jämförelseverktyget och se vad som har ändrats.