Jq

From wikinotes

parse json on the commandline.

TODO:

the official docs are very good, but syntax could be documented consistently with other languages. (ex: datatypes etc)

Documentation

official docs https://stedolan.github.io/jq/manual/
basic filters docs https://stedolan.github.io/jq/manual/#Basicfilters
homepage https://stedolan.github.io/jq/

Usage

Parameters

jq ${params..} ${query} [${file}]

jq \
  -r  `# 'raw' remove quotes from retrieved strings` \
  -e  `# if result is 'true' exitcode is 0, if 'false' exitcode is 1`

Basics

# print w/ syntaxhighlighting
echo '{"one": 1, "two": {"a": "A"}}' \
  | jq

# get key ["one"]
echo '{"one": 1, "two": {"a": "A"}}' \
  | jq '.one'    # 1

# get nested-key ["two"]["a"]
echo '{"one": 1, "two": {"a": "A"}}' \
  | jq '.two.a'  # "A"

# get list item at index 1
echo '["a", "b", "c"]' \
  | jq '.[1]'  # "b"

# get 'a' key form every dict in list
echo '{"list": [{"a": 1}, {"a": 2}]}' \
  | jq '.list[].a'

Working with Types

# merge sub-objects with parent object
echo '{
    "categories": {
        "foo": {
            {"a": 1, "b": 2}
        },
        "bar": {
            {"a": 3, "b": 4}
        }
    }
}' \
  | jq '.categories | with_entries | map({ category: .key, a: .a })'
  # [
  #   { "category": "foo", "a" 1 },
  #   { "category": "bar", "a" 3 }
  # ]

Filters

jq '.'        # obj
jq '.one'     # obj["one"]
jq '.one?'    # obj["one"] (but no error if not exist)
jq '.one.two' # obj["one"]["two"]
jq '.[1]'     # obj[1]
jq '.[5:10]'  # list-items 5-10
jq '.[] | select(.name == "foo")           # all dicts in list where name=="foo"
jq '.[] | select(.id == (242, 1, 123))     # all dicts where id in (242, 1, 123)
jq 'any(.[]; .id == "foo")'                # true if any dict in list contains {"id": "foo"}
jq '.[].name | select(startswith("foo"))'  # all name keys from dicts that start with "foo"

jq '.[] | with_entries(select(.key | in({"id": 1, "name": 1})))'  # return subset of keys from dict (only: id, name)

Expressions

Selections within () are evaluated as expressions

Conditionals

Combined with jq -e, you can return true/false and map to an exitcode.

echo '{"a": "foo"}' \
  | jq -e '.a == "foo"' \
  && echo "success"

Operators

Used in expressions

+
-
*
/
%

Transform

You can compose new objects from the input object.

jq '{"fullname": (.firstname + .lastname)}'

Comments

Neither json nor jq support comments.
It's hacky, but you could pre-process the object to strip them, however.

echo '{
  // syntax-highlight as javascript

  "local_path": "/home/you", // your home dir

  // a network path
  "netwk_path": "//10.1.0.5/music"
}' \
  | sed 's?//[^"]*$??'
  | jq '.one'