OILS / doc / json.md View on Github | oilshell.org

161 lines, 110 significant
1---
2default_highlighter: oils-sh
3---
4
5JSON in Oils
6===========
7
8[JSON](https://www.json.org/) is used by both web services and command line
9tools, so a modern Unix shell needs to support it.
10
11Oils has a `json` builtin which you can use from bot OSH and YSH.
12
13It also has a parallel `json8` builtin with the same uage. See [J8
14Notation](j8-notation.html) for details on the encoding.
15
16<div id="toc">
17</div>
18
19The `json` **builtin** has `read` and `write` subcommands, which convert
20between serialized data languages and in-memory data structures.
21
22YSH data structures are like those in Python and JavaScript, so this
23correspondence is natural.
24
25## `json read` parses from `stdin`
26
27Usage:
28
29 json read (PLACE?)
30 json8 read (PLACE?)
31
32Examples:
33
34 $ cat stats.json
35 {"count": 42}
36
37 # Read from a file. By default, the variable _reply is written.
38 $ json read < stats.json
39
40 # Use = to pretty print an expression
41 $ = _reply
42 (Dict) {'count': 42}
43
44Specify a place to put the data:
45
46 $ json read (&myvar) < stats.json
47
48 $ = myvar
49 (Dict) {'count': 42}
50
51Use it in a pipeline:
52
53 # 'json read' is valid at the end of a pipeline (because YSH implements
54 # shopt -s lastpipe)
55 $ echo '{"count": 42}' | json read (&myvar)
56
57Failure with invalid input data:
58
59 $ echo '[ "incomplete"' | json read (&myvar) < invalid.json
60 [ "incomplete"
61 ^
62 json read: premature EOF
63
64 $ echo $?
65 1
66
67## `json write` prints to `stdout`
68
69Usage:
70
71 json write FLAGS* (EXPR)
72
73 EXPR is an expression that evaluates to a serializable object.
74
75 Flags:
76 --indent=2 Indentation size
77 --pretty=true Whether to add newlines for readability
78
79Examples:
80
81 # Create a Dict. As in JavaScript, keys don't require quotes.
82 $ var d = {name: "bob", age: 42}
83
84 # Print the Dict as JSON. By default, newlines are added for readability,
85 # with 2 space indentation.
86 $ json write (d)
87 {
88 "name": "bob",
89 "count": 42
90 }
91
92 $ json write --indent 4 (d)
93 {
94 "name": "bob",
95 "count": 42
96 }
97
98 $ json write --pretty=F (d)
99 {"name": "bob", "count": 42}
100
101Notes:
102
103- `--indent` is ignored if `--pretty` is false.
104
105### `write` builtin
106
107TODO
108
109 write --j8 hello there
110 write --json hello there # unicode replacement char
111
112## Filter Data Structures with YSH Expressions
113
114Once your data is deserialized, you can use YSH expression to operate on it.
115
116 $ echo '{"counts": [42, 99]}' | json read (&d)
117
118 $ = d['counts']
119 (List) [42, 99]
120
121 $ = d['counts'][1]
122 (Int) 99
123
124 # d->counts is a synonym for d["counts"]
125 $ json write (d->counts)
126 [
127 42,
128 99
129 ]
130
131Note: It may more efficient to filter large data structures with tools like
132`jq` first.
133
134## Other Data Structures Can Be Printed as JSON
135
136YSH arrays and shell arrays both serialize to a list of strings:
137
138 $ declare sharray=( foo.txt *.py )
139 $ json write (sharray)
140 [
141 "foo.txt",
142 "one.py",
143 "two.py"
144 ]
145
146 $ var oilarray = :| foo.txt *.py |
147 $ json write (oilarray)
148 [
149 "foo.txt",
150 "one.py",
151 "two.py"
152 ]
153
154Bash-style associative arrays are printed like `Dict[Str, Str]`:
155
156 $ declare -A assoc=(["key"]=value)
157 $ json write (assoc)
158 {
159 "key": "value"
160 }
161