Slik sammenligner du to YAML-filer uten å snuble i innrykk
Den raskeste måten å sammenligne to YAML-filer på er å lime inn begge i et diff-verktøy som viser dem side om side, normalisere innrykket og lese linjene det fremhever. Sammenligningen er den enkle delen. Med YAML er støyen lurere enn vanlig: en forvillet tabulator, en ombyttet nøkkel eller en verdi som noen satte i anførselstegn, kan få to filer som lastes til samme data til å se ut som om de ikke har noe til felles.
Denne guiden går gjennom hvordan du får en ren, pålitelig YAML-diff. Vi ser på hvorfor to likeverdige filer driver fra hverandre på papiret, hvilke metoder som er verdt å kunne, og et gjennomarbeidet eksempel du kan følge. Hvis du bare vil ha verktøyet, gjør vår YAML-sammenligningsside alt dette i nettleseren.
Hvorfor YAML-filer er bedragersk vanskelige å sammenligne
YAML er et format som er følsomt for blanktegn (se YAML 1.2.2-spesifikasjonen), og det er nettopp det som gjør differ vanskelige. Innrykk bærer mening, men mengden innrykk gjør det ikke, så lenge den er konsekvent. Så en fil innrykket med to mellomrom og en annen med fire kan lastes til identisk struktur mens hver linje ser forskjellig ut for en tekstdiff.
Her er det viktige å holde fast ved: en YAML-mapping er et sett med nøkkel/verdi-par, og som JSON-objekter endrer ikke rekkefølgen på disse nøklene dataene. Så dette:
name: Ada Lovelace
role: editor
og dette:
role: editor
name: Ada Lovelace
lastes til samme mapping, selv om en linjediff maler dem røde og grønne. Sekvenselementer er derimot ordnet, så å bytte om en liste er en reell endring.
| Hva du ser i diffen | Er det en reell endring? | Hva du gjør |
|---|---|---|
| 2 vs 4 mellomroms innrykk | Nei, bare konsekvens betyr noe | Reformater begge til samme bredde |
| Mapping-nøkler i en annen rekkefølge | Nei, mappinger er uordnede | Sorter nøkler på begge sider |
true vs "true" | Ja, boolean vs streng | Undersøk det, dette er reelt |
name: Ada vs name: "Ada" | Nei, samme strengverdi | Normaliser anførselstegn |
Flytstil [a, b] vs blokkliste | Nei, samme sekvens | Velg én stil for begge |
| Sekvenselementer i en annen rekkefølge | Ja, sekvenser er ordnet | Undersøk det, dette er reelt |
To rader der er ekte feller. true uten anførselstegn er en boolean;
med anførselstegn er det strengen "true", og det skillet har forårsaket reelle
nedetider. Men name: Ada og name: "Ada" er den samme
strengen. Hvis du vil ha de tekniske detaljene om hvordan en parser løser dette,
er spesifikasjonens avsnitt om
core schema
referansen.
Fire måter å sammenligne YAML på, og når du skal gripe til hver
Det finnes ingen enkelt beste metode. Det avhenger av hvor filene er, og hva du prøver å finne ut. Slik står de vanlige alternativene.
| Metode | Best for | Innsats | Forstår YAML? |
|---|---|---|---|
| Å se det med øyet | Bittesmå filer, én eller to nøkler | Lav | Nei, du er parseren |
| Online diff-verktøy | Raske sjekker, lim inn fra hvor som helst | Lav | Med reformatering, ja |
Kommandolinje (yq) | Filer på disk, skripting, sortering av nøkler | Middels | Ja, når du sorterer først |
IDE eller git diff | Filer allerede i et repo | Lav hvis committet | Linjebasert som standard |
For de fleste vinner et nettleserverktøy på hastighet: ingenting å installere, og du kan lime inn et fragment rett fra et Kubernetes-manifest eller en CI-konfigurasjon. Haken er formateringsstøy, som vi tar tak i neste gang. Hvis du lever i terminalen, er yq verktøyet å lære, og det kan sortere nøkler på samme måte som jq gjør for JSON.
Den raskeste rene sammenligningen, steg for steg
Dette er rutinen jeg bruker når noen rekker meg to manifester og spør "hva er forskjellen?". Det tar omtrent femten sekunder.
- Åpne YAML-sammenligningsverktøyet.
- Lim inn originalen til venstre, den nye versjonen til høyre.
- Klikk på Formater på begge sider så de deler samme innrykk.
- Slå på sorter nøkler så ombyttede mapping-nøkler slutter å dukke opp som endringer.
- Les resultatet. Grønt er lagt til, rødt er fjernet, og en endret verdi vises som én av hver.
Steg tre og fire er hele trikset. Når begge filene bruker samme innrykk og nøklene deres er sortert, er det eneste som gjenstår å fremheve det som faktisk er endret. Diff-motoren vår er bygget på Googles diff-match-patch, som sammenligner linje for linje først, så den forblir rask selv på lange filer.
Et gjennomarbeidet eksempel
La oss si at du gjennomgår en endring i en brukerpost. Her er før:
name: Ada Lovelace
role: editor
active: true
seats: 3
Og her er etter, slik en kollega rakte den til deg:
active: true
name: Ada Lovelace
role: admin
seats: 5
team: platform
Slipp dem inn i en rå linjediff, og det ser ut som om nesten hver linje har flyttet seg, fordi nøklene er i en annen rekkefølge. Reformater og sorter begge, og den reelle historien er kort:
| Nøkkel | Før | Etter | Endring |
|---|---|---|---|
role | editor | admin | Endret |
seats | 3 | 5 | Endret |
team | — | platform | Lagt til |
name | Ada Lovelace | Ada Lovelace | Ingen endring |
active | true | true | Ingen endring (bare flyttet) |
Tre reelle endringer: en rolleopprykk, et seteantall og en ny team-nøkkel.
Ombyttingen var støy. Det opprykket fra editor til
admin er nøyaktig den typen ting du vil fange i en gjennomgang, og
det er lett å overse når det er begravd under falske alarmer.
Å drepe formateringsstøyen på kommandolinjen
Hvis filene dine allerede er på disk, fungerer den samme "reformater og
sorter"-ideen med to korte kommandoer. yq kan sortere nøkler og
sende ut en kanonisk form på nytt, så en vanlig diff etterpå er ærlig:
yq -P 'sort_keys(..)' old.yaml > old.sorted.yaml
yq -P 'sort_keys(..)' new.yaml > new.sorted.yaml
diff old.sorted.yaml new.sorted.yaml
Nå rapporterer diff bare verdier som virkelig er endret, fordi begge
filene har samme innrykk og samme nøkkelrekkefølge. Dette er
terminalekvivalenten til å klikke på Formater og sorter nøkler i nettleseren.
Fellene som er unike for YAML
Noen få YAML-funksjoner forårsaker differ som overrasker folk. Anchors og aliases
(&name og *name) lar én fil gjenta en verdi via
referanse mens en annen skriver den ut i sin helhet; begge lastes til samme data,
men leses helt forskjellig. Det beryktede "Norge-problemet" er et annet:
usiterte no, off og yes kan tolkes som
booleans i eldre YAML 1.1-parsere, så country: NO kan bli
false. YAML 1.2 fikset skjemaet, men mange verktøy leverer fortsatt
1.1-oppførsel. Når en verdi ser ut til å ha byttet type, er det det første du bør
sjekke.
Vanlige fallgruver å se opp for
| Fallgruve | Hvorfor den biter | Løsning |
|---|---|---|
| Tabulatorer til innrykk | YAML forbyr tabulatorer til innrykk; filen blir kanskje ikke engang parset | Konverter tabulatorer til mellomrom først |
| Siterte vs usiterte skalarer | "true" er en streng, true er en boolean | Dette kan være en reell endring, ikke avfei den |
| Anchors og aliases | Én fil setter inn en verdi inline, den andre refererer til den | Løs opp anchors, sammenlign så den utvidede formen |
| Norge-problemet | no kan tolkes som false i YAML 1.1 | Siter tvetydige strenger; sjekk parserversjonen din |
| Etterfølgende blanktegn | Usynlige mellomrom etter en verdi vises som en endring | Trim etterfølgende blanktegn før sammenligning |
YAML og JSON er nærmere hverandre enn de ser ut
Hvert JSON-dokument er gyldig YAML, fordi YAML 1.2 er et supersett av JSON. Det er praktisk for sammenligning: hvis innrykket eller anchors plager deg, konverter begge filene til JSON, formater dem på samme måte, og diff det i stedet. Mange parsere, inkludert PyYAML, kjører YAML frem og tilbake til en enkel datastruktur du kan sende ut på nytt som JSON, noe som fjerner de stilistiske forskjellene og etterlater bare dataene.
Relaterte verktøy
YAML reiser sjelden alene. Hvis du sammenligner JSON-formen av de samme dataene,
bruker JSON-sammenligning den samme ideen.
Miljøinnstillinger og .env-filer stiller seg pent opp på siden for
konfigurasjonssammenligning, og å gjennomgå
endringer mellom to API-kall er det
API-svardiffen er bygget for.
Ofte stilte spørsmål
- Laster sammenligning av YAML-filer online dem opp noe sted?
- På comparetext.org kjører diffen i nettleseren din. De to YAML-filene sammenlignes av JavaScript på din egen maskin, så ingenting sendes til en server med mindre du eksplisitt klikker på Lagre eller Del. Det gjør det trygt for Kubernetes-manifester, CI-konfigurasjoner og andre data du ikke ville ønsket å lime inn på et nettsted som laster opp ved hvert tastetrykk.
- Hvorfor viser de to YAML-filene mine hver linje som forskjellig?
- Nesten alltid er det formatering, ikke reelle endringer. Én fil er innrykket med to mellomrom, den andre med fire, eller mapping-nøklene er i en annen rekkefølge, eller én bruker anførselstegn og den andre ikke. Reformater begge sider til samme innrykk og sorter nøklene så rekkefølgen slutter å bety noe. Etter det krymper diffen vanligvis til den håndfullen verdier som virkelig er endret.
- Betyr innrykksbredde noe ved sammenligning av YAML?
- Ikke for betydningen, bare for konsekvensen. YAML bruker innrykk til å vise struktur, men bryr seg ikke om du bruker to eller fire mellomrom, så lenge hvert nivå er konsekvent innenfor filen. Så en fil med to mellomrom og en fil med fire kan inneholde identiske data mens de ser helt forskjellige ut for en tekstdiff. Å reformatere begge til samme bredde fjerner den falske forskjellen. Tabulatorer er derimot ikke tillatt til innrykk i det hele tatt.
- Hvordan sammenligner jeg YAML mens jeg ignorerer nøkkelrekkefølge?
- YAML-mapping-nøkler er uordnede, så to filer med samme nøkler i en annen rekkefølge inneholder de samme dataene. For at en tekstdiff skal være enig, sorter nøklene på begge sider før sammenligning. I nettleseren bruker du alternativet sorter nøkler (kanonisering). På kommandolinjen gjør yq det med sort_keys. Når begge filene har nøkler i samme sorterte rekkefølge, vises bare reelle verdiendringer. Sekvenselementer beholder rekkefølgen, så ikke sorter dem.
- Hva er Norge-problemet i YAML?
- Det er en klassisk YAML-felle der den usiterte verdien NO tolkes som booleanen false i stedet for strengen "NO", så en landkode for Norge blir false. Det skjer i YAML 1.1-parsere, som behandler yes, no, on og off som booleans. YAML 1.2 snevret inn reglene, men mange verktøy leverer fortsatt 1.1-oppførsel. Hvis en verdi ser ut til å ha snudd fra et ord til true eller false i diffen din, er en usitert boolean-lignende streng den sannsynlige årsaken. Å sitere verdien fikser det.
- Kan jeg sammenligne store YAML-filer uten at siden fryser?
- Ja, opp til et visst punkt. En diff i linjemodus forblir rask på filer med tusenvis av linjer fordi den sammenligner hele linjer først i stedet for hvert tegn. Svært store filer (flere megabyte) håndteres bedre med et kommandolinjeverktøy som yq eller git diff, som strømmer dataene. For alt du komfortabelt kan scrolle gjennom i en nettleser, er en online-diff det raskere alternativet.
Klar til å prøve det? Lim inn filene dine i YAML-sammenligningsverktøyet og se hva som er endret.