Need help with jd?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

josephburnett
273 Stars 28 Forks MIT License 184 Commits 9 Opened issues

Description

JSON diff and patch

Services available

!
?

Need anything else?

Contributors list

# 85,641
Kuberne...
Elixir
Clojure
Erlang
163 commits
# 131,598
PHP
Shell
raft-pr...
raft-al...
3 commits
# 696,552
Go
HTML
3 commits
# 156,360
Kotlin
mocks
mocking...
mockito
2 commits
# 247,839
OCaml
Amazon ...
applica...
PureScr...
1 commit

JSON diff and patch

jd
is a commandline utility and Go library for diffing and patching JSON values.

Try it out

http://play.jd-tool.io/

Command line usage

Download latest release or

go get github.com/josephburnett/jd
Diff and patch JSON files.

Prints the diff of FILE1 and FILE2 to STDOUT. When FILE2 is omitted the second input is read from STDIN. When patching (-p) FILE1 is a diff.

Options: -p Apply patch FILE1 to FILE2 or STDIN. -o=FILE3 Write to FILE3 instead of STDOUT. -set Treat arrays as sets. -mset Treat arrays as multisets (bags). -setkeys Keys to identify set objects -yaml Read and write YAML instead of JSON. -port=N Serve web UI on port N

Examples: jd a.json b.json cat b.json | jd a.json jd -o patch a.json b.json; jd patch a.json jd -set a.json b.json

Library usage

go get github.com/josephburnett/jd
import (
    "fmt"
    jd "github.com/josephburnett/jd/lib"
)

func ExampleJsonNode_Diff() { a, _ := jd.ReadJsonString({"foo":"bar"}) b, _ := jd.ReadJsonString({"foo":"baz"}) fmt.Print(a.Diff(b).Render()) // Output: // @ ["foo"] // - "bar" // + "baz" }

func ExampleJsonNode_Patch() { a, _ := jd.ReadJsonString(["foo"]) diff, _ := jd.ReadDiffString(`` + @ [1] + "\n" + + "bar" + "\n") b, _ := a.Patch(diff) fmt.Print(b.Json()) // Output: // ["foo","bar"] }

Diff language

Railroad diagram of EBNF

  • A diff is zero or more sections
  • Sections start with a
    @
    header and the path to a node
  • A path is a JSON list of zero or more elements accessing collections
  • A JSON number element (e.g.
    0
    ) accesses an array
  • A JSON string element (e.g.
    "foo"
    ) accesses an object
  • An empty JSON object element (
    {}
    ) accesses an array as a set or multiset
  • After the path is one or more removals or additions, removals first
  • Removals start with
    -
    and then the JSON value to be removed
  • Additions start with
    +
    and then the JSON value to added

EBNF

Diff ::= ( '@' '[' ( 'JSON String' | 'JSON Number' | 'Empty JSON Object' )* ']' '\n' ( ( '-' 'JSON Value' '\n' )+ | '+' 'JSON Value' '\n' ) ( '+' 'JSON Value' '\n' )* )*

Examples

@ ["a"]
- 1
+ 2
@ [2]
+ {"foo":"bar"}
@ ["Movies",67,"Title"]
- "Dr. Strangelove"
+ "Dr. Evil Love"
@ ["Movies",67,"Actors","Dr. Strangelove"]
- "Peter Sellers"
+ "Mike Myers"
@ ["Movies",102]
+ {"Title":"Austin Powers","Actors":{"Austin Powers":"Mike Myers"}}
@ ["Movies",67,"Tags",{}]
- "Romance"
+ "Action"
+ "Comedy"

Cookbook

Use git diff to produce a structural diff:

git difftool -yx jd @ -- foo.json
@ ["foo"]
- "bar"
+ "baz"

See what changes in a Kuberentes Deployment:

kubectl get deployment example -oyaml > a.yaml
kubectl edit deployment example
# change cpu resource from 100m to 200m
kubectl get deployment example -oyaml | jd -yaml a.yaml

output:

diff
@ ["metadata","annotations","deployment.kubernetes.io/revision"]
- "2"
+ "3"
@ ["metadata","generation"]
- 2
+ 3
@ ["metadata","resourceVersion"]
- "4661"
+ "5179"
@ ["spec","template","spec","containers",0,"resources","requests","cpu"]
- "100m"
+ "200m"
@ ["status","conditions",1,"lastUpdateTime"]
- "2021-12-23T09:40:39Z"
+ "2021-12-23T09:41:49Z"
@ ["status","conditions",1,"message"]
- "ReplicaSet \"nginx-deployment-787d795676\" has successfully progressed."
+ "ReplicaSet \"nginx-deployment-795c7f5bb\" has successfully progressed."
@ ["status","observedGeneration"]
- 2
+ 3
apply these change to another deployment: ```

edit file "patch" to contain only the hunk updating cpu request

kubectl patch deployment example2 --type json --patch "$(jd -t jd2patch ~/patch)" ```

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.