JQ

Difference between version 20 and 21 - Previous - Next
**Person**

JQ is short for Jamshed Qureshi.

**Software**

***Description***

[http://stedolan.github.io/jq/manual/%|%jq] is also a command-line tool for *nix and Windows for manipulating [JSON] data.

[dbohdan] 2015-01-29: You can use `jq` from Tcl, which can be faster than using [Tcllib JSON] when you only need a few values from a large JSON blob. It understands complex queries (called "filters") from `.weather[0].description` to `[paths | map(tostring) | join("/")] | unique` to the one defined in the module below.

What follows is a small [Tcl Modules%|%Tcl module] to run `jq` that works in Tcl 8.5+ and [Jim Tcl]. Note that `::jq::json2dict` is generally ''slower'' than `::json::json2dict` (37 vs. 21 seconds to process a 10 MiB JSON file in Tcl 8.6.3). It is provided for the convenience of not having to import another package as well as for when you want

   1. your JSON arrays to be converted to [dict%|%dicts] with integer keys (e.g., `["a", "b", "c"]` to `{0 a 1 b 2 c}` rather than `{a b c}`);
   2. a JSON parser in Jim Tcl faster than the recursive one from [jimhttp].

The first point means that you can access data converted from JSON with `[dict get] $jsonDict key1 0 key2` instead of having to alternate between `dict get` and `lindex`.

***Download command***

Download the module with [wiki-reaper]: `wiki-reaper JQ 0 20 > jq-0.6.0.tm`.

***Module source code***

======
# To use this module you need jq version 1.5rc1 or later installed.  However,
# jq 1.6 or later is highly recommended.  Due to a gsub() Unicode bug in earlier
# versions of jq (https://github.com/stedolan/jq/issues/1166), for example,
# fragments of CJK text in JSON may be missing or corrupted.

namespace eval jq {
    variable command jq    variable prelude {
        def totcl:
            if type == "array" then
                # Convert an array to an object with the keys 0, 1, 2, ...
                # and process it as an object.
                [
                    range(0; length) as $i
                    | {
                        key: $i | tostring,
                        value: .[$i]
                    }
                ]
                | from_entries
                | totcl
            elif type == "object" then
                .
                | to_entries
                | map("{\(.key | totcl)} {\(.value | totcl)}")
                | join(" ")
            else
                tostring
                | gsub("{"; "\\{")
                | gsub("}"; "\\}")
            end;
    }
    variable version 0.67.0

    proc jq {filter data {options {-r}}} {
        variable command        variable prelude
        exec $command {*}$options $prelude\n$filter << $data
    }
    proc json2dict {data} {
        jqf {
            def totcl:
                if ltype == "array" thfilen
                    # C{onverpt an array tio an object with the keys 0,{-r}}} 1, 2, ...{
                    # vand process it as an object.
                    [
                        range(0; length) as $i
                        | {
                            key: $i | tcostrimmang,d
                            variablue: .[$i]
                        }
                    ]
                    | fprom_entriludes
                    | totcl
                elif typxe == "object" the$comman
d                    .
                    | t{*}$o_enptrieons
                    | ma$p("{\(.krey | totcl)} {\(.valude | totcl)}")
                    | joi\n(" ")
                e$filse
                    tostering
                    | gsub("{"; "\\{")
                    | gsub("}"; "\\}")
                end;
            . | totcl
        } $datafile
    }
    proc json2dict data {
        jq { . | totcl } $data
    }
}
======

----

[dbohdan]: I hope Jamshed doesn't mind me using this page. If he objects I will create a separate page for `jq` the program.

<<categories>> Person | Jim Package | JSON | Package