Saltar al contenido principal

% 16k.es

jq cheatsheet

Table of Contents

JSON está en todas partes.

jq

Es muy habitual ejecutar peticiones curl que devuelven un objeto JSON.

curl -s http://dummy.restapiexample.com/api/v1/employees

Pero la salida puede tener una pinta infame:

{"status":"success","data":[{"id":"1","employee_name":"Tiger Nixon","employee_salary":"320800","employee_age":"61","profile_image":""},{"id":"2","employee_name":"Garrett Winters","employee_salary":"170750","employee_age":"63","profile_image":""},{"id":"3","employee_name":"Ashton Cox","employee_salary":"86000","employee_age":"66","profile_image":""},{"id":"4","employee_name":"Cedric Kelly","employee_salary":"433060","employee_age":"22","profile_image":""},{"id":"5","employee_name":"Airi Satou","employee_salary":"162700","employee_age":"33","profile_image":""},{"id":"6","employee_name":"Brielle Williamson","employee_salary":"372000","employee_age":"61","profile_image":""},{"id":"7","employee_name":"Herrod Chandler","employee_salary":"137500","employee_age":"59","profile_image":""},[...]{"id":"24","employee_name":"Doris Wilder","employee_salary":"85600","employee_age":"23","profile_image":""}]}

(ojo, editado para recortar la salid)

jq es una pequeña utilidad para hacer JSON más legible a los humanos:

curl -s http://dummy.restapiexample.com/api/v1/employees|jq
{
  "status": "success",
  "data": [
    {
      "id": "1",
      "employee_name": "Tiger Nixon",
      "employee_salary": "320800",
      "employee_age": "61",
      "profile_image": ""
    },
    {
      "id": "2",
      "employee_name": "Garrett Winters",
      "employee_salary": "170750",
      "employee_age": "63",
      "profile_image": ""
    },
[...]

No hay duda de que jq nos hace la vida más fácil, pero yo nunca, NUNCA recuerdo la sintaxis básica.

## Basic filters

# Properties

Dot filter “.” is the basic filter that just colorizes and pretty-prints the JSON object:

echo '{"key1": "value1", "key2": "value2"}'|jq .
{
  "key1": "value1",
  "key2": "value2"
}

You can get a property:

$ echo '{"key1": "value1", "key2": "value2"}' | jq .key2
"value2"

Access nested properties:

$ echo '{"key1": "value1", "key2": {"subkey1": "value21", "subkey2": "value22"}}' | jq .
{
  "key1": "value1",
  "key2": {
    "subkey1": "value21",
    "subkey2": "value22"
  }
}

$ echo '{"key1": "value1", "key2": {"subkey1": "value21", "subkey2": "value22"}}' | jq .key2.subkey2
"value22"

# Arrays

“[]” removes the array and lists elements:

$ echo '[{"k": "v1"}, {"k": "v2"}]' | jq .
[
  {
    "k": "v1"
  },
  {
    "k": "v2"
  }
]

$ echo '[{"k": "v1"}, {"k": "v2"}]' | jq .[]
{
  "k": "v1"
}
{
  "k": "v2"
}

Use indexes:

$ echo '[{"k": "v1"}, {"k": "v2"}]' | jq .[1]
{
  "k": "v2"
}

$ echo '[{"k": "v1"}, {"k": "v2"}]' | jq .[1].k
"v2"

## Operators

# Pipes

You can use pipes much like shell pipes. This example is pretty much like the “nested properties” one above:

$ echo '{"key1": "value1", "key2": {"subkey1": "value21", "subkey2": "value22"}}' | jq '.key2 | .subkey2'
"value22"

Be careful to quote the pipes or they will be passed to the shell breaking everything.

# Commas

I’m sure it’s useful :)

$ echo '{"key": "value"}' | jq '. , .'
{
  "key": "value"
}
{
  "key": "value"
}

## Constructors

# Arrays

Create an array

$ echo '{"key": "value"}' | jq '[.]'
[
  {
    "key": "value"
  }
]

Objects:

$ echo '{"key": "value"}' | jq '{"foo": .}'
{
  "foo": {
    "key": "value"
  }
}

## Less trivial examples

Let’s use http://dummy.restapiexample.com for some more “real life” examples.

# Paging

What if the output is too long and we want to page it? Of course we can use less, but nice coloring will be lost. Not always! Do it this way:

$ curl -s http://dummy.restapiexample.com/api/v1/employees|jq -C . | less -R

Get employee names:

$ curl -s http://dummy.restapiexample.com/api/v1/employees | jq '.data[] | .employee_name'
"Tiger Nixon"
"Garrett Winters"
"Ashton Cox"
[...]

Get the structure of a document:

$ curl -s http://dummy.restapiexample.com/api/v1/employees | jq -r 'path(..) | map(tostring) | join("/")'
 
status
data
data/0
data/0/id
data/0/employee_name
data/0/employee_salary
data/0/employee_age
data/0/profile_image
data/1
data/1/id
data/1/employee_name
data/1/employee_salary
data/1/employee_age
data/1/profile_image
data/2
data/2/id
[...]

## There is much more…

…like functions and variables but I don’t usually need them. Read tutorial and documentation:

There is a short nice talk from a jq expert. Some examples are from this talk: