- jq
- data
- Options
- Types and Values
- Built-in Functions
length
keys
/keys_unsorted
has(key)
map(x)
/map_values(x)
path(path_expression)
del(path_expression)
getpath(PATHS)
setpath(PATHS; VALUE)
to_entries
,from_entries
,with_entries
select(boolean_expression)
arrays
,objects
,iterables
,booleans
,numbers
,normals
,finites
,strings
,nulls
,values
,scalars
paths
add
any
/all
/any(condition)
/all(condition)
range(upto)
/range(from; upto)
/range(from; to; by)
tonumber
/tostring
type
sort
/sort_by(path_expression)
group_by(path_expression)
min
/max
/min_by(path_exp)
/max_by(path_exp)
unique
/unique_by(path_exp)
reverse
contains(element)
indices(s)
index(s)
/rindex(s)
inside(s)
startswith(str)
/endswith(str)
combinations
/combinations(n)
ltrimstr(str)
/rtrimstr(str)
explode
/implode
split(s)
/join(s)
ascii_upcase
/ascii_downcase
while(crondition; update)
/until(crondition; next)
- Examples
jq
=====
data
$ cat /tmp/data
{
"Subnets": [
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "DEV",
"Key": "Env"
},
{
"Value": "AccountBase",
"Key": "aws:cloudformation:stack-name"
},
{
"Value": "PrivateSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "Systems",
"Key": "Owner"
},
{
"Value": "PrivateSubnet1a",
"Key": "Name"
}
],
"AvailableIpAddressCount": 214,
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"State": "available",
"MapPublicIpOnLaunch": false,
"SubnetId": "subnet-xxxxxx",
"CidrBlock": "10.1.2.0/24",
"AssignIpv6AddressOnCreation": false
},
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "Systems",
"Key": "Owner"
},
{
"Value": "AccountBase",
"Key": "aws:cloudformation:stack-name"
},
{
"Value": "PublicSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "DEV",
"Key": "Env"
}
],
"AvailableIpAddressCount": 250,
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"State": "available",
"MapPublicIpOnLaunch": false,
"SubnetId": "subnet-yyyyyy",
"CidrBlock": "10.1.0.0/24",
"AssignIpv6AddressOnCreation": false
}
]
}
Options
-S
sort keys
$ cat /tmp/jq-data | jq -r -S '.Subnets[0]'
{
"AssignIpv6AddressOnCreation": false,
"AvailabilityZone": "us-east-1a",
"AvailableIpAddressCount": 214,
"CidrBlock": "10.1.2.0/24",
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"MapPublicIpOnLaunch": false,
"State": "available",
"SubnetId": "subnet-xxxxxx",
"Tags": [
{
"Key": "Env",
"Value": "DEV"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "AccountBase"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "PrivateSubnet1a"
},
{
"Key": "Owner",
"Value": "Systems"
},
{
"Key": "Name",
"Value": "PrivateSubnet1a"
}
]
}
-c
compact output
$ cat /tmp/jq-data | jq -c
{"Subnets":[{"AvailabilityZone":"us-east-1a","Tags":[{"Value":"DEV","Key":"Env"},{"Value":"AccountBase","Key":"aws:cloudformation:stack-name"},{"Value":"PrivateSubnet1a","Key":"aws:cloudformation:logical-id"},{"Value":"Systems","Key":"Owner"},{"Value":"PrivateSubnet1a","Key":"Name"}],"AvailableIpAddressCount":214,"DefaultForAz":false,"Ipv6CidrBlockAssociationSet":[],"State":"available","MapPublicIpOnLaunch":false,"SubnetId":"subnet-xxxxxx","CidrBlock":"10.1.2.0/24","AssignIpv6AddressOnCreation":false},{"AvailabilityZone":"us-east-1a","Tags":[{"Value":"Systems","Key":"Owner"},{"Value":"AccountBase","Key":"aws:cloudformation:stack-name"},{"Value":"PublicSubnet1a","Key":"aws:cloudformation:logical-id"},{"Value":"DEV","Key":"Env"}],"AvailableIpAddressCount":250,"DefaultForAz":false,"Ipv6CidrBlockAssociationSet":[],"State":"available","MapPublicIpOnLaunch":false,"SubnetId":"subnet-yyyyyy","CidrBlock":"10.1.0.0/24","AssignIpv6AddressOnCreation":false}]}
-f
read filter from file
$ cat /tmp/filter
.Subnets[].AvailabilityZone
$ cat /tmp/jq-data | jq -r -f /tmp/filter
us-east-1a
us-east-1a
--arg
/ --argjson
pass parameters from bash
$ test_cidr='10.1.0.*'
$ jq -r --arg cidr "${test_cidr}" '.Subnets[] | {cidr: .CidrBlock} | select(.cidr | test($cidr))' /tmp/data
{
"cidr": "10.1.0.0/24"
}
parameter as an integer
$ avaiable_ips_threshhold=220
$ jq -r --argjson ip_threshhold "${avaiable_ips_threshhold}" '.Subnets[] | {subnetid: .SubnetId, AvailableIp: .AvailableIpAddressCount} | select(.AvailableIp > $ip_threshhold)' /tmp/data
{
"subnetid": "subnet-yyyyyy",
"AvailableIp": 250
}
$ jq -r --arg ip_threshhold "${avaiable_ips_threshhold}" '.Subnets[] | {subnetid: .SubnetId, AvailableIp: .AvailableIpAddressCount} | select(.AvailableIp > ($ip_threshhold | tonumber))' /tmp/jq-data
{
"subnetid": "subnet-yyyyyy",
"AvailableIp": 250
}
--slrupfile
reads JSON from file
and binds to a global variable
$ cat /tmp/filter | jq .
{
"avaiable_ips_threshhold": 220
}
$ jq -r --slurpfile var /tmp/filter '$var' /tmp/jq-data
[
{
"avaiable_ips_threshhold": 220
}
]
$ jq -r --slurpfile var /tmp/filter '.Subnets[] | {subnetid: .SubnetId, AvailableIp: .AvailableIpAddressCount} | select(.AvailableIp > $var[0].avaiable_ips_threshhold)' /tmp/jq-data
{
"subnetid": "subnet-yyyyyy",
"AvailableIp": 250
}
Types and Values
..
Recursive Descent
Built-in Functions
length
gets the length of various different types of value
$ cat /tmp/data | jq '.Subnets | length'
2
Count elements based on some specifict conditions
$ jq -r '.Subnets[] | select(.State == "available") | length' /tmp/data
10
10
$ jq -r '[.Subnets[] | select(.State == "available")] | length' /tmp/data
2
keys
/ keys_unsorted
returns its keys in an array
$ cat /tmp/data | jq '. | keys[]'
"Subnets"
$ cat /tmp/data | jq '.Subnets[0] | keys_unsorted '
[
"AvailabilityZone",
"Tags",
"AvailableIpAddressCount",
"DefaultForAz",
"Ipv6CidrBlockAssociationSet",
"State",
"MapPublicIpOnLaunch",
"SubnetId",
"CidrBlock",
"AssignIpv6AddressOnCreation"
]
$ cat /tmp/data | jq '.Subnets | keys[]'
0
1
has(key)
returns whether the input object has the given key / in
returns the input key is in the given object, or the input index corresponds to an element in the given array
$ cat /tmp/data | jq 'has("Subnets")'
true
$ cat /tmp/data | jq '. | keys[] | in({"Subnets": 1})'
true
$ cat /tmp/data | jq '.Subnets | keys[]'
0
1
$ cat /tmp/data | jq '[2] | keys[]'
0
$ cat /tmp/data | jq '.Subnets | keys[] | in([2])'
true
false
# given array '[2]' has only one index: 0
map(x)
/ map_values(x)
apply filter x
to each element of the input array
$ cat /tmp/data | jq '.Subnets | keys'
[
0,
1
]
$ cat /tmp/data | jq '.Subnets | keys | map(.+1)'
[
1,
2
]
path(path_expression)
returns array representations of the given path expression in .
. The outputs are arrays of strings (object keys) and/or numbers (array indices).
$ cat /tmp/data | jq '.Subnets[0].SubnetId'
"subnet-xxxxxx"
$ cat /tmp/data | jq 'path(.Subnets[0].SubnetId)'
[
"Subnets",
0,
"SubnetId"
]
del(path_expression)
removes a key and its corresponding value
$ cat /tmp/data | jq '.Subnets[] | del(.Tags)'
{
"AvailabilityZone": "us-east-1a",
"AvailableIpAddressCount": 214,
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"State": "available",
"MapPublicIpOnLaunch": false,
"SubnetId": "subnet-xxxxxx",
"CidrBlock": "10.1.2.0/24",
"AssignIpv6AddressOnCreation": false
}
{
"AvailabilityZone": "us-east-1a",
"AvailableIpAddressCount": 250,
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"State": "available",
"MapPublicIpOnLaunch": false,
"SubnetId": "subnet-yyyyyy",
"CidrBlock": "10.1.0.0/24",
"AssignIpv6AddressOnCreation": false
}
getpath(PATHS)
returns the values in of each PATHS
.
$ cat /tmp/data| jq 'getpath(["Subnets", 0, "AvailableIpAddressCount"], ["Subnets", 1, "AvailableIpAddressCount"])'
214
250
setpath(PATHS; VALUE)
set VALUE
for PATHS
.
$ cat /tmp/data| jq 'setpath(["Subnets", 0, "AvailableIpAddressCount"]; 0) | .Subnets[].AvailableIpAddressCount'
0
250
to_entries
, from_entries
, with_entries
to_entries
converts an array to {"key": k, "value": v}
.
from_entries
converts on the opposite way.
with_entries(filter)
is same as to_entries | map(filter) | from_entries
$ cat /tmp/data | jq '.Subnets[].Tags | from_entries'
{
"Env": "DEV",
"aws:cloudformation:stack-name": "AccountBase",
"aws:cloudformation:logical-id": "PrivateSubnet1a",
"Owner": "Systems",
"Name": "PrivateSubnet1a"
}
{
"Owner": "Systems",
"aws:cloudformation:stack-name": "AccountBase",
"aws:cloudformation:logical-id": "PublicSubnet1a",
"Env": "DEV"
}
$ cat /tmp/data | jq '.Subnets[] | to_entries | map(select(.key == "AvailableIpAddressCount"))'
[
{
"key": "AvailableIpAddressCount",
"value": 214
}
]
[
{
"key": "AvailableIpAddressCount",
"value": 250
}
]
$ cat /tmp/data | jq '.Subnets[] | with_entries(select(.key == "AvailableIpAddressCount"))'
{
"AvailableIpAddressCount": 214
}
{
"AvailableIpAddressCount": 250
}
select(boolean_expression)
produces its input unchanged if it returns true for that input, and produces no output otherwise.
arrays
, objects
, iterables
, booleans
, numbers
, normals
, finites
, strings
, nulls
, values
, scalars
selects above objects as result
paths
outputs the paths to all the elements, which is similar as path(..)
paths(filter)
output the paths which value match filter
$ cat /tmp/data | jq 'paths(select(.Key? == "Env"))'
[
"Subnets",
0,
"Tags",
0
]
[
"Subnets",
1,
"Tags",
3
]
$ cat /tmp/data | jq 'getpath(["Subnets", 0, "Tags", 0])'
{
"Value": "DEV",
"Key": "Env"
}
$ cat /tmp/data | jq 'getpath(["Subnets", 1, "Tags", 3])'
{
"Value": "DEV",
"Key": "Env"
}
add
add all elements of input array
$ cat /tmp/data | jq '[.Subnets[].AvailableIpAddressCount] | add'
464
$ cat /tmp/data | jq '[.Subnets[].AvailabilityZone] | add'
"us-east-1aus-east-1a"
$ cat /tmp/data | jq '[.Subnets[] | .AvailabilityZone, .AvailableIpAddressCount | tostring] | add'
"us-east-1a214us-east-1a250"
any
/ all
/ any(condition)
/ all(condition)
any
takes an array of boolean values, and returns true
if any of them are true
all
takes an array of boolean values, and returns true
if all of them are true
any(condition)
applies condition
to all elements of given array, and returns true
if any of them are true
all(condition)
applies condition
to all elements of given array, and returns true
if all of them are true
$ cat /tmp/data | jq '[.Subnets[0].AvailableIpAddressCount > 220, .Subnets[1].AvailableIpAddressCount > 220] | any '
true
$ cat /tmp/data | jq '[.Subnets[].AvailableIpAddressCount] | any(. > 220)'
true
$ cat /tmp/data | jq '[.Subnets[].AvailableIpAddressCount] | all(. > 220)'
false
range(upto)
/ range(from; upto)
/ range(from; to; by)
generates a range of numbers from
until upto
with step by
tonumber
/ tostring
convert input to number or string
type
returns the type of inputs
sort
/ sort_by(path_expression)
sort an array with following order:
null
false
true
- nubmers
- strings (alphabetical order)
- array (lexical order)
- object
or sort the array based onvalue
ofpath_expression
```bash $ jq -r ‘[.Subnets[].AvailableIpAddressCount]’ /tmp/data [ 250, 214 ]
$ jq -r ‘[.Subnets[].AvailableIpAddressCount] | sort’ /tmp/data [ 214, 250 ]
### `group_by(path_expression)`
takes as input an array, groups the elements having the same `path_expression` field value into separate arrays, and produces all of these arrays as elements of a larger array.
```bash
$ echo '[{"a": 1}, {"b": 2}, {"a": 1}, {"a": 2}]' | jq 'group_by(.a)'
[
[
{
"b": 2
}
],
[
{
"a": 1
},
{
"a": 1
}
],
[
{
"a": 2
}
]
]
min
/ max
/ min_by(path_exp)
/ max_by(path_exp)
get min or max element of input array
$ cat /tmp/data | jq '[.Subnets[].AvailableIpAddressCount] | min '
214
$ cat /tmp/data | jq '[.Subnets[].AvailableIpAddressCount] | max '
250
$ cat /tmp/data | jq '.Subnets | min_by(.AvailableIpAddressCount)'
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "DEV",
"Key": "Env"
},
{
"Value": "AccountBase",
"Key": "aws:cloudformation:stack-name"
},
{
"Value": "PrivateSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "Systems",
"Key": "Owner"
},
{
"Value": "PrivateSubnet1a",
"Key": "Name"
}
],
"AvailableIpAddressCount": 214,
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"State": "available",
"MapPublicIpOnLaunch": false,
"SubnetId": "subnet-xxxxxx",
"CidrBlock": "10.1.2.0/24",
"AssignIpv6AddressOnCreation": false
}
$ cat /tmp/data | jq '.Subnets | max_by(.AvailableIpAddressCount)'
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "Systems",
"Key": "Owner"
},
{
"Value": "AccountBase",
"Key": "aws:cloudformation:stack-name"
},
{
"Value": "PublicSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "DEV",
"Key": "Env"
}
],
"AvailableIpAddressCount": 250,
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"State": "available",
"MapPublicIpOnLaunch": false,
"SubnetId": "subnet-yyyyyy",
"CidrBlock": "10.1.0.0/24",
"AssignIpv6AddressOnCreation": false
}
unique
/ unique_by(path_exp)
produces an array without duplicated elements from input array.
$ cat /tmp/data | jq '[.Subnets[].Tags[]] | unique'
[
{
"Value": "DEV",
"Key": "Env"
},
{
"Value": "PrivateSubnet1a",
"Key": "Name"
},
{
"Value": "Systems",
"Key": "Owner"
},
{
"Value": "PrivateSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "PublicSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "AccountBase",
"Key": "aws:cloudformation:stack-name"
}
]
$ cat /tmp/data | jq '[.Subnets[].Tags[]] | unique_by(.Key)'
[
{
"Value": "DEV",
"Key": "Env"
},
{
"Value": "PrivateSubnet1a",
"Key": "Name"
},
{
"Value": "Systems",
"Key": "Owner"
},
{
"Value": "PublicSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "AccountBase",
"Key": "aws:cloudformation:stack-name"
}
]
reverse
reverses an input array
contains(element)
evaluate the element
was included in input
$ cat /tmp/data | jq '.Subnets[].AvailabilityZone | contains("east")'
true
true
$ cat /tmp/data | jq '.Subnets[].Tags[] | contains({"Key": "Env"})'
false
false
false
true
true
false
false
false
false
indices(s)
returns index of s
or value of key s
$ echo '[{"a": 1}, {"b": 2}, {"a": 1}, {"a": 2}]' | jq '.[] | indices("a")'
1
null
1
2
$ echo '[{"a": 1}, {"b": 2}, {"a": 1}, {"a": 2}]' | jq 'indices({"a": 2})'
[
3
]
index(s)
/ rindex(s)
returns the first index of s
or last index of s
$ echo '[{"a": 1}, {"b": 2}, {"a": 1}, {"a": 2}]' | jq 'index({"a": 1})'
0
$ echo '[{"a": 1}, {"b": 2}, {"a": 1}, {"a": 2}]' | jq 'rindex({"a": 1})'
2
inside(s)
inversed version of contains
startswith(str)
/ endswith(str)
$ cat /tmp/data | jq '[.Subnets[0].Tags[] | {key: .Key, value: .Value}] | from_entries[] '
"Systems"
"AccountBase"
"PublicSubnet1a"
"DEV"
$ cat /tmp/data | jq '[.Subnets[0].Tags[] | {key: .Key, value: .Value}] | from_entries[] | startswith("Sys")'
true
false
false
false
$ cat /tmp/data | jq '[.Subnets[0].Tags[] | {key: .Key, value: .Value}] | from_entries[] | endswith("Base")'
false
true
false
false
combinations
/ combinations(n)
outputs all combinations of the elements of input arrays. With n
means to output n
repetitions of input array
$ echo '[[1, 2], [3, 4]]' | jq 'combinations'
[
1,
3
]
[
1,
4
]
[
2,
3
]
[
2,
4
]
$ echo '[[1, 2], [3, 4]]' | jq 'combinations(2)'
[
[
1,
2
],
[
1,
2
]
]
[
[
1,
2
],
[
3,
4
]
]
[
[
3,
4
],
[
1,
2
]
]
[
[
3,
4
],
[
3,
4
]
]
ltrimstr(str)
/ rtrimstr(str)
trims input string from left or right
explode
/ implode
convert string to Unicode code point, or convert Unicode code point to string
$ echo '"matrix"' | jq 'explode'
[
109,
97,
116,
114,
105,
120
]
$ echo "[109, 97, 116, 114, 105, 120]" | jq 'implode'
"matrix"
split(s)
/ join(s)
split input based by splitter s
or join all elements with splitter s
$ echo '["matrix"]' | jq '.'
[
"matrix"
]
$ echo '["matrix"]' | jq '.[] | split("")'
[
"m",
"a",
"t",
"r",
"i",
"x"
]
$ echo '["matrix"]' | jq '.[] | split("") | join("")'
"matrix"
ascii_upcase
/ ascii_downcase
convert input to UpperCase or Lowercase
$ echo '["matrix"]' | jq '.[] | ascii_upcase'
"MATRIX"
while(crondition; update)
/ until(crondition; next)
run update
while contidion
is true
run next
until until condition
is true
$ echo 5 | jq '[., ., 1] | [while(.[1] > 0; [.[0], .[1] - 1, .[2] * .[1]])] | .[length -1][2]'
120
$ echo 5 | jq '[., 1] | until(.[0] < 1; [.[0] - 1, .[1] * .[0]]) | .[1]'
120
Examples
Show all keys
$ cat /tmp/data | jq '. | keys[]'
"Subnets"
$ cat /tmp/data | jq '.Subnets | keys[]'
0
1
Show Specific Element by Index
$ cat /tmp/data | jq '.Subnets[0]'
{
"AvailabilityZone": "us-east-1a",
"Tags": [
{
"Value": "DEV",
"Key": "Env"
},
{
"Value": "AccountBase",
"Key": "aws:cloudformation:stack-name"
},
{
"Value": "PrivateSubnet1a",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "Systems",
"Key": "Owner"
},
{
"Value": "PrivateSubnet1a",
"Key": "Name"
}
],
"AvailableIpAddressCount": 214,
"DefaultForAz": false,
"Ipv6CidrBlockAssociationSet": [],
"State": "available",
"MapPublicIpOnLaunch": false,
"SubnetId": "subnet-xxxxxx",
"CidrBlock": "10.1.2.0/24",
"AssignIpv6AddressOnCreation": false
}
Show Multi Attibutes
$ cat /tmp/data | jq '.Subnets[].SubnetId, .Subnets[].CidrBlock'
"subnet-xxxxxx"
"subnet-yyyyyy"
"10.1.2.0/24"
"10.1.0.0/24"
$ cat /tmp/data | jq '.Subnets[] | .SubnetId, .CidrBlock'
"subnet-xxxxxx"
"10.1.2.0/24"
"subnet-yyyyyy"
"10.1.0.0/24"
Filter by value
$ cat /tmp/data | jq '.Subnets[] | .SubnetId, .CidrBlock | select( . == "10.1.0.0/24" )'
"10.1.0.0/24"
$ cat /tmp/data | jq '.Subnets[] | .SubnetId, .CidrBlock | select( . | test(".*1.0.*") )'
"10.1.0.0/24"
$ cat /tmp/data | jq '.Subnets[] | {id: .SubnetId, network: .CidrBlock} | select(.network == "10.1.0.0/24")'
{
"id": "subnet-yyyyyy",
"network": "10.1.0.0/24"
}
Resharp json
$ cat /tmp/data | jq '.Subnets[] | { id: .SubnetId, ip_range: .CidrBlock }'
{
"id": "subnet-xxxxxx",
"ip_range": "10.1.2.0/24"
}
{
"id": "subnet-yyyyyy",
"ip_range": "10.1.0.0/24"
}
skip null iterator with ?
$ cat /tmp/ss-instances | jq ' .[][].Instances[] | {id: .InstanceId, tags: .Tags[]} | select(.tags.Key | test("^Name$";"i")) | select(.tags.Value | test(".*netapp.*"))'
jq: error (at <stdin>:34578): Cannot iterate over null (null)
$ cat /tmp/ss-instances | jq ' .[][].Instances[] | {id: .InstanceId, tags: .Tags[]?} | select(.tags.Key | test("^Name$";"i")) | select(.tags.Value | test(".*netapp.*"))'
{
"id": "i-0908ac3819044a7b4",
"tags": {
"Value": "fwawsnetapp01-mediator",
"Key": "Name"
}
}
filter case insensitive with "i"
$ cat /tmp/ss-instances | jq ' .[][].Instances[] | {id: .InstanceId, tags: .Tags[]?} | select(.tags.Key | test("^Name$";"i")) | select(.tags.Value | test(".*netapp.*";"i"))'
{
"id": "i-0b92c0aa4b6758489",
"tags": {
"Value": "System-NetAppCloudManager",
"Key": "Name"
}
}
{
"id": "i-0908ac3819044a7b4",
"tags": {
"Value": "fwawsnetapp01-mediator",
"Key": "Name"
}
}
filter value based on another is existed
$ cat /tmp/data
{
"Subnets": [
{
"AvailabilityZone": "us-east-1a",
"SubnetId": "subnet-xxxxxx"
},
{
"SubnetId": "subnet-yyyyyy"
}
]
}
$ jq '.Subnets[] | {az: .AvailabilityZone, subnet: .SubnetId} | select(.az != null).subnet ' /tmp/data
"subnet-xxxxxx"
combine 2 values
$ jq -r '.Subnets[] | (.AvailabilityZone + ", " + .CidrBlock)' /tmp/data
us-east-1a, 10.1.2.0/24
us-east-1a, 10.1.0.0/24
resharp result as an array
$ jq -r '[.Subnets[] | {info: (.AvailabilityZone + ", " + .CidrBlock)}]' /tmp/data
[
{
"info": "us-east-1a, 10.1.2.0/24"
},
{
"info": "us-east-1a, 10.1.0.0/24"
}
]
split
$ jq -r '.Subnets[] | .AvailabilityZone | split("-")[0]' /tmp/data
us
us
get substring with capture
Collects the named captures in a JSON object, with the name of each capture as the key, and the matched string as the corresponding value.
$ jq -r '.Subnets[].AvailabilityZone | capture("(?<country>[^-]+)")' /tmp/data
{
"country": "us"
}
{
"country": "us"
}