| 1 | ---
|
| 2 | default_highlighter: oils-sh
|
| 3 | ---
|
| 4 |
|
| 5 | JSON in Oils
|
| 6 | ===========
|
| 7 |
|
| 8 | [JSON](https://www.json.org/) is used by both web services and command line
|
| 9 | tools, so a modern Unix shell needs to support it.
|
| 10 |
|
| 11 | Oils has a `json` builtin which you can use from bot OSH and YSH.
|
| 12 |
|
| 13 | It also has a parallel `json8` builtin with the same uage. See [J8
|
| 14 | Notation](j8-notation.html) for details on the encoding.
|
| 15 |
|
| 16 | <div id="toc">
|
| 17 | </div>
|
| 18 |
|
| 19 | The `json` **builtin** has `read` and `write` subcommands, which convert
|
| 20 | between serialized data languages and in-memory data structures.
|
| 21 |
|
| 22 | YSH data structures are like those in Python and JavaScript, so this
|
| 23 | correspondence is natural.
|
| 24 |
|
| 25 | ## `json read` parses from `stdin`
|
| 26 |
|
| 27 | Usage:
|
| 28 |
|
| 29 | json read (PLACE?)
|
| 30 | json8 read (PLACE?)
|
| 31 |
|
| 32 | Examples:
|
| 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 |
|
| 44 | Specify a place to put the data:
|
| 45 |
|
| 46 | $ json read (&myvar) < stats.json
|
| 47 |
|
| 48 | $ = myvar
|
| 49 | (Dict) {'count': 42}
|
| 50 |
|
| 51 | Use 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 |
|
| 57 | Failure 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 |
|
| 69 | Usage:
|
| 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 |
|
| 79 | Examples:
|
| 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 |
|
| 101 | Notes:
|
| 102 |
|
| 103 | - `--indent` is ignored if `--pretty` is false.
|
| 104 |
|
| 105 | ### `write` builtin
|
| 106 |
|
| 107 | TODO
|
| 108 |
|
| 109 | write --j8 hello there
|
| 110 | write --json hello there # unicode replacement char
|
| 111 |
|
| 112 | ## Filter Data Structures with YSH Expressions
|
| 113 |
|
| 114 | Once 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 |
|
| 131 | Note: 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 |
|
| 136 | YSH 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 |
|
| 154 | Bash-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 |
|