.\"t .\" Automatically generated by Pandoc 1.19.2.1 .\" .TH "JO" "1" "" "User Manuals" "" .hy .SH NAME .PP jo \- JSON output from a shell .SH SYNOPSIS .PP jo [\-p] [\-a] [\-B] [\-v] [\-V] [\-\-] [ [\-s|\-n|\-b] word ...] .SH DESCRIPTION .PP \f[I]jo\f[] creates a JSON string on \f[I]stdout\f[] from _word_s given it as arguments or read from \f[I]stdin\f[]. Without option \f[C]\-a\f[] it generates an object whereby each \f[I]word\f[] is a \f[C]key=value\f[] (or \f[C]key\@value\f[]) pair with \f[I]key\f[] being the JSON object element and \f[I]value\f[] its value. \f[I]jo\f[] attempts to guess the type of \f[I]value\f[] in order to create number (using \f[I]strtod(3)\f[]), string, or null values in JSON. .PP \f[I]jo\f[] treats \f[C]key\@value\f[] specifically as boolean JSON elements: if the value begins with \f[C]T\f[], \f[C]t\f[], or the numeric value is greater than zero, the result is \f[C]true\f[], else \f[C]false\f[]. A missing or empty value behind the colon results in a \f[C]null\f[] JSON element. .PP \f[I]jo\f[] creates an array instead of an object when \f[C]\-a\f[] is specified. .PP When the \f[C]:=\f[] operator is used in a \f[I]word\f[], the name to the right of \f[C]:=\f[] is a file containing JSON which is parsed and assigned to the key left of the operator. .SH TYPE COERCION .PP \f[I]jo\f[]\[aq]s type guesses can be overridden on a per\-word basis by prefixing \f[I]word\f[] with \f[C]\-s\f[] for \f[I]string\f[], \f[C]\-n\f[] for \f[I]number\f[], or \f[C]\-b\f[] for \f[I]boolean\f[]. The list of _word_s \f[I]must\f[] be prefixed with \f[C]\-\-\f[], to indicate to \f[I]jo\f[] that there are no more global options. .PP Type coercion works as follows: .PP .TS tab(@); l l l l l. T{ word T}@T{ \-s T}@T{ \-n T}@T{ \-b T}@T{ default T} _ T{ a= T}@T{ "a":"" T}@T{ "a":0 T}@T{ "a":false T}@T{ "a":null T} T{ a=string T}@T{ "a":"string" T}@T{ "a":6 T}@T{ "a":true T}@T{ "a":"string" T} T{ a="quoted" T}@T{ "a":""quoted"" T}@T{ "a":8 T}@T{ "a":true T}@T{ "a":""quoted"" T} T{ a=12345 T}@T{ "a":"12345" T}@T{ "a":12345 T}@T{ "a":true T}@T{ "a":12345 T} T{ a=true T}@T{ "a":"true" T}@T{ "a":1 T}@T{ "a":true T}@T{ "a":true T} T{ a=false T}@T{ "a":"false" T}@T{ "a":0 T}@T{ "a":false T}@T{ "a":false T} T{ a=null T}@T{ "a":"" T}@T{ "a":0 T}@T{ "a":false T}@T{ "a":null T} .TE .PP Coercing a non\-number string to number outputs the \f[I]length\f[] of the string. .PP Coercing a non\-boolean string to boolean outputs \f[C]false\f[] if the string is empty, \f[C]true\f[] otherwise. .PP Type coercion only applies to \f[C]key=value\f[] words, and individual words in a \f[C]\-a\f[] array. Coercing other words has no effect. .SH EXAMPLES .PP Create an object. Note how the incorrectly\-formatted float value becomes a string: .IP .nf \f[C] $\ jo\ tst=1457081292\ lat=12.3456\ cc=FR\ badfloat=3.14159.26\ name="JP\ Mens"\ nada=\ coffee\@T {"tst":1457081292,"lat":12.3456,"cc":"FR","badfloat":"3.14159.26","name":"JP\ Mens","nada":null,"coffee":true} \f[] .fi .PP Pretty\-print an array with a list of files in the current directory: .IP .nf \f[C] $\ jo\ \-p\ \-a\ * [ \ "Makefile", \ "README.md", \ "jo.1", \ "jo.c", \ "jo.pandoc", \ "json.c", \ "json.h" ] \f[] .fi .PP Create objects within objects; this works because if the first character of value is an open brace or a bracket we attempt to decode the remainder as JSON. Beware spaces in strings ... .IP .nf \f[C] $\ jo\ \-p\ name=JP\ object=$(jo\ fruit=Orange\ hungry\@0\ point=$(jo\ x=10\ y=20\ list=$(jo\ \-a\ 1\ 2\ 3\ 4\ 5))\ number=17)\ sunday\@0 { \ "name":\ "JP", \ "object":\ { \ \ "fruit":\ "Orange", \ \ "hungry":\ false, \ \ "point":\ { \ \ \ "x":\ 10, \ \ \ "y":\ 20, \ \ \ "list":\ [ \ \ \ \ 1, \ \ \ \ 2, \ \ \ \ 3, \ \ \ \ 4, \ \ \ \ 5 \ \ \ ] \ \ }, \ \ "number":\ 17 \ }, \ "sunday":\ false } \f[] .fi .PP Booleans as strings or as boolean (pay particular attention to \f[I]switch\f[]; the \f[C]\-B\f[] option disables the default detection of the "\f[C]true\f[]", "\f[C]false\f[]", and "\f[C]null\f[]" strings): .IP .nf \f[C] $\ jo\ switch=true\ morning\@0 {"switch":true,"morning":false} $\ jo\ \-B\ switch=true\ morning\@0 {"switch":"true","morning":false} \f[] .fi .PP Elements (objects and arrays) can be nested. The following example nests an array called \f[I]point\f[] and an object named \f[I]geo\f[]: .IP .nf \f[C] $\ jo\ \-p\ name=Jane\ point[]=1\ point[]=2\ geo[lat]=10\ geo[lon]=20 { \ \ \ "name":\ "Jane", \ \ \ "point":\ [ \ \ \ \ \ \ 1, \ \ \ \ \ \ 2 \ \ \ ], \ \ \ "geo":\ { \ \ \ \ \ \ "lat":\ 10, \ \ \ \ \ \ "lon":\ 20 \ \ \ } } \f[] .fi .PP Type coercion: .IP .nf \f[C] $\ jo\ \-p\ \-\-\ \-s\ a=true\ b=true\ \-s\ c=123\ d=123\ \-b\ e="1"\ \-b\ f="true"\ \-n\ g="This\ is\ a\ test"\ \-b\ h="This\ is\ a\ test" { \ \ \ "a":\ "true", \ \ \ "b":\ true, \ \ \ "c":\ "123", \ \ \ "d":\ 123, \ \ \ "e":\ true, \ \ \ "f":\ true, \ \ \ "g":\ 14, \ \ \ "h":\ true } $\ jo\ \-a\ \-\-\ \-s\ 123\ \-n\ "This\ is\ a\ test"\ \-b\ C_Rocks\ 456 ["123",14,true,456] \f[] .fi .PP Read element values from files: a value which starts with \f[C]\@\f[] is read in plain whereas if it begins with a \f[C]%\f[] it will be base64\-encoded: .IP .nf \f[C] $\ jo\ program=jo\ authors=\@AUTHORS {"program":"jo","authors":"Jan\-Piet\ Mens\ "} $\ jo\ filename=AUTHORS\ content=%AUTHORS {"filename":"AUTHORS","content":"SmFuLVBpZXQgTWVucyA8anBtZW5zQGdtYWlsLmNvbT4K"} \f[] .fi .PP Read element values from a file in order to overcome ARG_MAX limits during object assignment: .IP .nf \f[C] $\ ls\ |\ jo\ \-a\ >\ child.json $\ jo\ files:=child.json {"files":["AUTHORS","COPYING","ChangeLog"\ .... \f[] .fi .SH OPTIONS .PP \f[I]jo\f[] understands the following global options. .TP .B \-a Interpret the list of \f[I]words\f[] as array values and produce an array instead of an object. .RS .RE .TP .B \-B By default \f[I]jo\f[] interprets the strings "\f[C]true\f[]" and "\f[C]false\f[]" as boolean elements \f[C]true\f[] and \f[C]false\f[] respectively, and "\f[C]null\f[]" as \f[C]null\f[]. Disable with this option. .RS .RE .TP .B \-p Pretty\-print the JSON string on output instead of the terse one\-line output it prints by default. .RS .RE .TP .B \-v Show version and exit. .RS .RE .TP .B \-V Show version as a JSON object and exit. .RS .RE .SH BUGS .PP Probably. .PP If a value given to \f[I]jo\f[] expands to empty in the shell, then \f[I]jo\f[] produces a \f[C]null\f[] in object mode, and might appear to hang in array mode; it is not hanging, rather it\[aq]s reading \f[I]stdin\f[]. This is not a bug. .PP Numeric values are converted to numbers which can produce undesired results. If you quote a numeric value, \f[I]jo\f[] will make it a string. Compare the following: .IP .nf \f[C] $\ jo\ a=1.0 {"a":1} $\ jo\ a=\\"1.0\\" {"a":"1.0"} \f[] .fi .PP Omitting a closing bracket on a nested element causes a diagnostic message to print, but the output contains garbage anyway. This was designed thusly. .SH RETURN CODES .PP \f[I]jo\f[] exits with a code 0 on success and non\-zero on failure after indicating what caused the failure. .SH AVAILABILITY .PP .SH CREDITS .IP \[bu] 2 This program uses \f[C]json.[ch]\f[], by Joseph A. Adams. .SH SEE ALSO .IP \[bu] 2 .IP \[bu] 2 .IP \[bu] 2 .IP \[bu] 2 strtod(3) .SH AUTHOR .PP Jan\-Piet Mens