Sådan sammenligner du to JSON-filer og finder hvad der er ændret
Den hurtigste måde at sammenligne to JSON-filer er at indsætte dem begge i et diff-værktøj side om side, formatere dem på samme måde og læse de linjer det fremhæver. Den svære del er normalt ikke selve sammenligningen. Det er støjen: omordnede nøgler, forskellig indrykning og løse afsluttende kommaer kan få to næsten identiske filer til at se ud som om de ikke deler noget som helst.
Denne guide gennemgår hvordan man får en ren og pålidelig diff. Vi ser på hvorfor JSON-filer drifter fra hinanden på papiret mens de forbliver ens i betydning, de få metoder der er værd at kende, og et gennemarbejdet eksempel du kan følge med i. Hvis du bare vil have værktøjet, gør vores JSON-sammenligningsside alt dette i browseren.
Hvorfor JSON-filer er bedragerisk svære at sammenligne
JSON har en lille, streng grammatik (se specifikationen på json.org), men giver forfattere stor frihed i hvordan de lægger teksten ud. To filer kan beskrive det nøjagtig samme objekt og alligevel adskille sig byte for byte. En almindelig tekstdiff ved intet af dette, så den flager trofast det hele.
Her er noget at internalisere inden du begynder: objektnøgler i JSON har
ingen rækkefølge. Specifikationen
(RFC 8259)
definerer et objekt som et uordnet sæt af navn/værdi-par. Så
{"name":"Ada","id":7} og {"id":7,"name":"Ada"}
er ens, selvom en linjesdiff vil male dem røde og grønne.
| Hvad du ser i diff'en | Er det en reel ændring? | Hvad du skal gøre |
|---|---|---|
| Nøgler i en anden rækkefølge | Nej, objekter er uordnede | Sorter nøgler på begge sider |
| 2-mellemrum vs 4-mellemrum indrykning | Nej | Formater begge sider ens |
| Minificeret vs pænt udskrevet | Nej | Formater begge sider |
| Afsluttende linjeskift i slutningen af filen | Nej | Ignorer, eller trim whitespace |
En værdi ændret fra "7" til 7 | Ja, streng vs tal | Undersøg, dette er reelt |
| Array-elementer i en anden rækkefølge | Måske, arrays er ordnede | Afgør om rækkefølgen betyder noget her |
Den sidste række overrasker folk. Arrays bevarer deres rækkefølge, objekter
gør det ikke. Så [1, 2, 3] og [3, 2, 1] er
genuint forskellige, men nøglerne inde i et objekt kan flyttes frit rundt.
Hvis du vil have de tekniske detaljer om hvordan JavaScript parser alt
dette, har MDN en solid
reference om JSON-objektet.
Fire måder at sammenligne JSON på, og hvornår man bruger hvilken
Der er ingen enkelt bedste metode. Det afhænger af hvor filerne befinder sig og hvad du forsøger at lære. Sådan klarer de almindelige muligheder sig.
| Metode | Bedst til | Indsats | Forstår JSON? |
|---|---|---|---|
| Se det igennem | Små filer, et eller to felter | Lav | Nej, du er parseren |
| Online diff-værktøj | Hurtige kontroller, indsætte fra alle steder | Lav | Med format + sorter nøgler, ja |
Kommandolinje (jq, diff) | Filer på disk, scripting, store filer | Mellem | Ja, når du sorterer først |
IDE eller git diff | Filer allerede i et repo | Lav hvis committed | Linjebaseret som standard |
For de fleste mennesker vinder et browserværktøj på hastighed fordi der ikke er noget at installere og du kan indsætte et uddrag direkte fra en log eller et API-kald. Ulempen er formateringsstøj, som vi tager os af næste. Hvis du lever på terminalen er jq værktøjet at lære, og vi viser det ene flag der betyder noget.
Den hurtigste rene sammenligning, trin for trin
Dette er den rutine jeg bruger når nogen rækker mig to konfigurationsfiler og spørger "hvad er anderledes?". Det tager cirka femten sekunder.
- Åbn JSON-sammenligningsværktøjet.
- Indsæt originalen til venstre, den nye version til højre.
- Klik på Formater på begge sider så de deler den samme indrykning.
- Slå sorter nøgler (kanoniser) til så omordnede nøgler ikke længere vises som ændringer.
- Læs resultatet. Grønt er tilføjet, rødt er fjernet, og en ændret værdi vises som en af hver.
Trin tre og fire er hele tricket. Når begge filer er identisk formaterede og deres nøgler er sorterede, er det eneste der er tilbage at fremhæve hvad der faktisk er ændret. Vores diff-motor er bygget på Googles diff-match-patch, der sammenligner linje for linje først så den forbliver hurtig selv på lange filer.
Et gennemarbejdet eksempel
Lad os sige du gennemgår en ændring af en brugerpost. Her er tilstanden før:
{
"name": "Ada Lovelace",
"role": "editor",
"active": true,
"seats": 3
}
Og her er tilstanden efter, som en holdkammerat rakte dig den:
{
"active": true,
"name": "Ada Lovelace",
"role": "admin",
"seats": 5,
"team": "platform"
}
Smid dem ind i en rå linjesdiff og det ligner at næsten alle linjer er rykket, fordi nøglerne er i en anden rækkefølge. Formater og sorter begge, og den rigtige historie er kort:
| Felt | Før | Efter | Ændring |
|---|---|---|---|
role | editor | admin | Ændret |
seats | 3 | 5 | Ændret |
team | — | platform | Tilføjet |
name | Ada Lovelace | Ada Lovelace | Ingen ændring |
active | true | true | Ingen ændring (kun flyttet) |
Tre reelle redigeringer: en rolleforfremmelse, et sædeantal og et nyt
teamfelt. Omordningen var støj. Den forfremmelse fra editor
til admin er præcis den slags ting du vil opfange i review,
og den er nem at overse når den er begravet under tyve linjer falske
positiver.
At eliminere formateringsstøj på kommandolinjen
Hvis dine filer allerede er på disk, fungerer den samme "formater og sorter"
idé med to korte kommandoer. Flaget -S fortæller jq at
sortere objektnøgler; at røre begge filer igennem det normaliserer dem
så en almindelig diff er ærlig:
jq -S . old.json > old.sorted.json
jq -S . new.json > new.sorted.json
diff old.sorted.json new.sorted.json
Nu rapporterer diff kun værdier der virkelig er ændret, fordi
begge filer har den samme indrykning og den samme nøglerækkefølge. Dette
er terminalækvivalenten til at klikke Formater og sorter nøgler i browseren.
Tekstdiff vs strukturel diff
Alt ovenstående er en tekstdiff: hurtig, visuel og perfekt for et
menneske der læser en ændring. En strukturel diff går videre og
beskriver ændringen som data. Standarden for det er JSON Patch, defineret i
RFC 6902,
der udtrykker redigeringer som operationer som replace og
add ved en given sti. Du vil have en strukturel diff når et
program skal anvende ændringen, ikke bare en person der ser på den.
Til daglig review er en tekstdiff med sorterede nøgler rigeligt.
Almindelige faldgruber at holde øje med
| Faldgrube | Hvorfor den bider | Løsning |
|---|---|---|
| Talpræcision | Heltal over 2^53 − 1 mister præcision i JavaScript | Sammenlign store ID'er som strenge; se MAX_SAFE_INTEGER |
| Unicode-escape | "café" og "café" er den samme streng, forskellige bytes | Formater begge sider, hvilket normaliserer kodningen |
| Duplikerede nøgler | De fleste parsere beholder stille den sidste | Valider JSON'en inden du stoler på diff'en |
| Afsluttende kommaer | Ikke lovlig JSON; en fil kan måske slet ikke parses | Ret syntaksen først, validatoren vil flage det |
| Streng vs tal | "5" og 5 ligner hinanden men er forskellige typer | Dette er en reel ændring, afvis den ikke |
Relaterede værktøjer
JSON er sjældent det eneste format du har med at gøre. Hvis du sammenligner konfiguration på tværs af miljøer anvender YAML-sammenligning den samme idé på YAML. At gennemgå ændringer mellem to API-kald er hvad API-responsdiff-værktøjet er bygget til, og afhængighedsopdateringer er nemmest at læse på package.json diff-siden.
Ofte stillede spørgsmål
- Uploader sammenligning af JSON-filer online dem et sted?
- På comparetext.org kører diff'en i din browser. De to JSON-filer sammenlignes af JavaScript på din egen maskine, så intet sendes til en server medmindre du eksplicit klikker Gem eller Del. Det gør det sikkert til konfigurationsfiler, API-svar og andre data du ikke ville ønske at indsætte på et tilfældig website der uploader ved hvert tastetryk.
- Hvorfor viser mine to JSON-filer hver linje som anderledes?
- Næsten altid er det formatering, ikke reelle ændringer. En fil er minificeret eller indrykket med tabs, den anden med to mellemrum, eller objektnøglerne er i en anden rækkefølge. Klik på Formater på begge sider så de bruger den samme indrykning, sorter derefter nøglerne så rækkefølge holder op med at betyde noget. Derefter krymper diff'en normalt til de få værdier der virkelig er ændret.
- Hvordan sammenligner jeg JSON mens jeg ignorerer nøglerækkefølge?
- JSON-objektnøgler har ingen defineret rækkefølge, så
{"a":1,"b":2}og{"b":2,"a":1}er ens. For at få en tekstdiff til at være enig, sorter nøglerne på begge sider inden sammenligning. I browseren, brug kanoniser (sorter nøgler) indstillingen. På kommandolinjen gør jq det:jq -S . file.json. Når begge filer har nøgler i den samme sorterede rækkefølge, dukker kun reelle værdiændringer op. - Kan jeg sammenligne store JSON-filer uden at siden fryser?
- Ja, op til et punkt. En linjesdiff forbliver hurtig på filer med tusindvis af linjer fordi den sammenligner hele linjer først i stedet for hvert tegn. Meget store filer (adskillige megabytes) håndteres bedre med et kommandolinjeværktøj som jq eller git diff, der streamer data. For alt du komfortabelt kan scrolle igennem i en browser er en online diff den hurtigere mulighed.
- Hvad er forskellen mellem en tekstdiff og en strukturel diff af JSON?
- En tekstdiff sammenligner filerne linje for linje, på samme måde som den ville sammenligne to essays. En strukturel diff forstår JSON, så den ved at en omordnet nøgle ikke er en ændring og at en værdi der er rykket inde i et array er et flyt, ikke en sletning plus en tilføjelse. Tekstdiff'er er hurtigere og gode nok til de fleste reviews. Strukturelle diff'er (for eksempel JSON Patch per RFC 6902) betyder noget når du skal beskrive en ændring som data et program kan anvende.
- Hvordan sammenligner jeg to API-svar?
- Gem hvert svar til en fil eller kopiér det fra din browsers netværksfane, indsæt derefter det gamle svar til venstre og det nye til højre. Formater begge så indrykning matcher, og sorter nøgler hvis API'et ikke returnerer dem i en stabil rækkefølge. Værktøjet api-response-diff er afstemt til præcis dette: at spotte et omdøbt felt, en ændret statuskode, eller en værdi der flippede fra en streng til et tal mellem to kald.
Klar til at prøve det? Indsæt dine filer i JSON-sammenligningsværktøjet og se hvad der er ændret.