Jq: Difference between revisions

From wikinotes
 
(5 intermediate revisions by the same user not shown)
Line 19: Line 19:
= Usage =
= Usage =
<blockquote>
<blockquote>
== Parameters ==
<blockquote>
<syntaxhighlight lang="bash">
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`
</syntaxhighlight>
</blockquote><!-- Parameters -->
== Basics ==
== Basics ==
<blockquote>
<blockquote>
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# print w/ syntaxhighlighting
# print w/ syntaxhighlighting
echo '{"one": 1, "two": {"a": "A"}}' | jq
echo '{"one": 1, "two": {"a": "A"}}' \
  | jq


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


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


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


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


</blockquote><!-- Basics -->
</blockquote><!-- Basics -->
== Working with Types ==
<blockquote>
<syntaxhighlight lang="bash">
# 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 }
  # ]
</syntaxhighlight>
</blockquote><!-- Working with Types -->


== Filters ==
== Filters ==
Line 49: Line 88:
jq '.[5:10]'  # list-items 5-10
jq '.[5:10]'  # list-items 5-10
jq '.[] | select(.name == "foo")          # all dicts in list where name=="foo"
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 '.[].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)
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- Filters -->
</blockquote><!-- Filters -->
Line 57: Line 100:
Selections within <code>()</code> are evaluated as expressions
Selections within <code>()</code> are evaluated as expressions
</blockquote><!-- Expressions -->
</blockquote><!-- Expressions -->
== Conditionals ==
<blockquote>
Combined with <code>jq -e</code>, you can return true/false and map to an exitcode.
<syntaxhighlight lang="bash">
echo '{"a": "foo"}' \
  | jq -e '.a == "foo"' \
  && echo "success"
</syntaxhighlight>
</blockquote><!-- Conditionals -->


== Operators ==
== Operators ==

Latest revision as of 16:55, 19 February 2023

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'