jq

最後更新: 2023-07-04

介紹

jq is sed for JSON (Command-line JSON processor)

jq is written in portable C, and it has zero runtime dependencies.

HomePage: https://stedolan.github.io/jq/

Default: running the filter for each JSON object in the input

目錄

 


Install

 

apt-get install jq

dnf install jq

 


Opts

 

--raw-output / -r            

if the filter´s result is a string then it will be written directly to stdout
rather than being formatted as a JSON string with quotes.

--compact-output / -c

JSON object on a single line

--null-input / -n

Don ´t read any input at all! Instead, the filter is run once using null as the input.

i.e.

jq -nr 'now'

1696493958.188751

 


Json file

 

boxs.json

{"Boxs":[
{"x": 1, "y": 2, "z": 3},
{"x": 4, "y": 5, "z": 6},
{"x": 7, "y": 8, "z": 9}]}

 

 


Usage

 

Pretty-print

# The simplest filter is "." which echoes its input, but pretty-printed:

echo '{"hello":{ "greetings":"to you"}}' | jq .

Or

jq . file.json

 * . refers to the input

Notes: keep colors when piping "jq" output to "less"

By default, jq outputs colored JSON if writing to a terminal.

You can force it to produce color even if writing to a pipe or a file using -C

curl -s http://localhost:9200/_nodes | jq -C .nodes | less -r

Field

single field: '.expression'

# ".field" which pulls "field" out of each record:

i.e.

echo '{"hello":{ "greetings":"to you"}}' | jq .hello

{
  "greetings": "to you"
}

nested data: '.expression.expression'

i.e.

echo '{"hello":{ "greetings":"to you"}}' | jq .hello.greetings

"to you"

取出兩個 Field: '.foo, .bar'

i.e.

echo '{"foo": 42, "bar": "string", "baz": true}' | jq '.foo, .bar'

42
"string"

P.S. 在 list of array 時寫法有所不同

jq '.Boxs[] | .x, .y' boxs.json

jq '.Boxs[].x, .Boxs[].y' boxs.json

Array

Array Index

# 0, 1, 2 ... *

.[N]

'length'

echo '["a","b","c","d","e"]' | jq 'length'

5

array - '[]'

jq '.Boxs' boxs.json          # a array of object

jq '.Boxs[]' boxs.json       # 一個個 object

jq '.Boxs[]' boxs.json

--slurp/-s:

read the entire input stream into a large array and run the filter just once.
(Default: running the filter for each JSON object in the input)

jq '.Boxs[]' boxs.json | jq -s

jq '.Boxs[]' boxs.json | jq [.]

Go “into” the array

.[]

.[] = Array/Object Value Iterator

有 go “into” Array/Object 的作用

.[]?

Like .[], but no errors will be output if . is not an array or object.

Slice - "[start-index:end-index]"

echo '["a","b","c","d","e"]' | jq '.[2:4]'

.[-3:-1]       # length = 2. 獲得 [-3], [-2]
.[-3:]          # length = 3. 獲得 [-3], [-2], [-1]

 

Labels

Adding labels to identifier values. To make this output easier to read

{<label>: <expression>, <label>: <expression>}

e.g.

 


Sort

 

  • sort
  • sort_by(.foo)

sort

sort a array.

Order

  1. null
  2. false / true
  3. numbers
  4. strings
  5. arrays
  6. objects

echo '[8,3,null,6]' | jq sort -c

[null,3,6,8]

'reverse'

echo '[8,3,null,6]' | jq sort | jq -c 'reverse'

[8,6,3,null]

sort_by(.foo)

compares two elements by comparing the result of foo on each element.

[{"foo":4, "bar":10}, {"foo":3, "bar":100}, {"foo":2, "bar":1}]
=> [{"foo":2, "bar":1}, {"foo":3, "bar":100}, {"foo":4, "bar":10}]

 


map

 

map(filter) / map_values(x)

run filter for each element of the input array, and return the outputs in a new array.

filter

  • has,
  • in,
  • select

select(boolean_expression)

echo '[1,2,3]' | jq -c 'map(select(. >= 2))'

[2,3]

echo '["a", "b", "c"]' | jq -c 'map(select(. >= "b"))'

["b","c"]   # ASCII a=141, b=142

# 由於用了 ".[]" 所以不用 map()

echo '[{"id": "first", "val": 1}, {"id": "second", "val": 2}]'  |  jq -c '.[] | select(.id == "second")'

{"id":"second","val":2}

has(key)

# returns whether the input object has the given key

echo '[{"foo": 42}, {"bar":37}]' | jq -c 'map(has("foo"))'

[true,false]

# returns array has an element at the given index.

echo '[["a", "b", "c"], ["e", "f"]]' | jq -c 'map(has(2))'

[true,false]

echo '[["a", "b", "c"], ["e", "f"]]' | jq .[0][2]

"c"

 


String

 

split(D) -> Array

cat list.txt | jq '.RecoveryPoints[] | .CreationDate|split("T")[0]' | less

cat list.txt | jq '.RecoveryPoints[] | .CreationDate[0:10]' | less

 


Date

 

jq -nr 'now'

1696493958.188751

jq -nr 'now | todate'

2023-10-05T08:48:06Z

jq -nr '"2023-10-05T08:48:06Z" | fromdate'

1696495686

strftime(fmt)    # builtin formats a time (GMT) with the given format. P.S. strflocaltime

jq -nr 'now | strftime("%Y-%m-%dT%H:%M:%S")'

2023-10-05T08:19:53

日期轉 unix timestamp

 * 由於 fromdate 只認 "%Y-%m-%dT%H:%M:%SZ" 格式(ISO 8601), 所以唔可以用它轉 timestamp

jq -nr '"2022-09-11T01:00:00+08:00"[0:19]+"Z"'

2022-09-11T01:00:00Z

 

 


Example

 

#1 找出 array 內每個 item 的 feild

ip-ranges.json

[
  {
    "ip_prefix": "3.2.34.0/26",
    "region": "af-south-1",
    "service": "AMAZON",
    "network_border_group": "af-south-1"
  },
  {
    "ip_prefix": "3.5.140.0/22",
    "region": "ap-northeast-2",
    "service": "AMAZON",
    "network_border_group": "ap-northeast-2"
  },
  ...
]

# "| .text" filter by text

cat ip-ranges.json | jq .prefixes | jq ".[] | .ip_prefix"

Notes

jq ".[] | .ip_prefix" 可以簡寫成  jq ".[].ip_prefix"

P.S.

AWC CloudFront 的 IP List: https://ip-ranges.amazonaws.com/ip-ranges.json

#2 在 elasticsearch 找出每個 node

curl -s http://localhost:9200/_nodes/ | jq '.nodes | keys'

# node 的基本資料

curl -s http://localhost:9200/_nodes/ | jq '.nodes | .[] | .name, .ip, .version, .roles, .attributes'

#3 Remove Old AWS Backup

# 獲得 resource-arn

aws backup list-protected-resources

# 找出 recovery-points

aws backup list-recovery-points-by-resource \
    --resource-arn "arn:aws:ec2:ap-east-1:..." > backup_list.txt

# Filter 出 90 日前的 Backup

cat list.txt | jq '.RecoveryPoints[] | select(.CreationDate[0:19]+"Z" | fromdate < (now - 7776000))' > old_backup.txt

cat old_backup.txt | jq '.RecoveryPointArn' > delete_list.txt

delete_bak.sh

#!/bin/bash

VAULT="VAULT_NAME"

while read line
do
        aws backup delete-recovery-point \
                --backup-vault-name "$VAULT" \
                --recovery-point-arn "${line:1:-1}"
done < "delete_list.txt"

 

Creative Commons license icon Creative Commons license icon