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

147 lines, 99 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 (EXPR, space=2)
72
73 EXPR is an expression that evaluates to a serializable object.
74
75 space is the number of spaces that object and array entries are indented
76 by. If it's 0 or less, then no newlines or spaces are printed.
77
78Examples:
79
80 $ var d = {name: "bob", age: 42} # create Dict
81
82 $ json write (d) # print as JSON, with 2 space indent
83 {
84 "name": "bob",
85 "count": 42
86 }
87
88 $ json write (d, space=0) # no indent at all
89 {"name":"bob","count":42}
90
91### `write` builtin
92
93TODO
94
95 write --j8 hello there
96 write --json hello there # unicode replacement char
97
98## Filter Data Structures with YSH Expressions
99
100Once your data is deserialized, you can use YSH expression to operate on it.
101
102 $ echo '{"counts": [42, 99]}' | json read (&d)
103
104 $ = d['counts']
105 (List) [42, 99]
106
107 $ = d['counts'][1]
108 (Int) 99
109
110 # d->counts is a synonym for d["counts"]
111 $ json write (d->counts)
112 [
113 42,
114 99
115 ]
116
117Note: It may more efficient to filter large data structures with tools like
118`jq` first.
119
120## Other Data Structures Can Be Printed as JSON
121
122YSH arrays and shell arrays both serialize to a list of strings:
123
124 $ declare sharray=( foo.txt *.py )
125 $ json write (sharray)
126 [
127 "foo.txt",
128 "one.py",
129 "two.py"
130 ]
131
132 $ var oilarray = :| foo.txt *.py |
133 $ json write (oilarray)
134 [
135 "foo.txt",
136 "one.py",
137 "two.py"
138 ]
139
140Bash-style associative arrays are printed like `Dict[Str, Str]`:
141
142 $ declare -A assoc=(["key"]=value)
143 $ json write (assoc)
144 {
145 "key": "value"
146 }
147