jq: Cheat Sheet
Learn essential commands for filtering, transforming, and manipulating JSON data with this quick reference guide. Perfect for developers and data analysts working with JSON!
jq is a lightweight and flexible command-line JSON processor. It allows for filtering, transforming, and manipulating JSON data.
General Usage
Pretty Print
Reformat the content of a file to include uniform indentation and new lines to make the JSON content easier to read. The
. is the identity filter which produces the input as output and unchanged. By default jq pretty prints output so
this is a convenient way to pretty print ant content.
Assume the following is the ugly content of the file example.json:
{
"name": "John",
"age": 30,
"city": "New York",
"pets": [
{
"name": "Fido",
"species": "Dog",
"age": 5
},
{
"name": "Whiskers",
"species": "Cat",
"age": 3
}
]
}
This command will pretty print the content of the file:
jq . example.json
This is the output:
{
"name": "John",
"age": 30,
"city": "New York",
"pets": [
{
"name": "Fido",
"species": "Dog",
"age": 5
},
{
"name": "Whiskers",
"species": "Cat",
"age": 3
}
]
}
Extract property
jq .the.dot.path.to.property < some.json
Extract property without quotes
jq -r .the.path < some.json
Minify
Reformat the content of a file to remove indentations and newlines.
Assume the following is the content of the file example.json:
{
"name": "John",
"age": 30,
"city": "New York",
"pets": [
{
"name": "Fido",
"species": "Dog",
"age": 5
},
{
"name": "Whiskers",
"species": "Cat",
"age": 3
}
]
}
This command will minify the content of the file:
jq -c . example.json
This is the output:
{
"name": "John",
"age": 30,
"city": "New York",
"pets": [
{
"name": "Fido",
"species": "Dog",
"age": 5
},
{
"name": "Whiskers",
"species": "Cat",
"age": 3
}
]
}
Get first element in array
jq .[0] some.json
Get properties from objects in array
jq '.[] | {.id, .name}' some.json
DataDog, get interesting properties from export as array:
This query takes a JSON file containing Datadog monitor data, and extracts a subset of the fields for each monitor,
including the id, name, query, message, created, creator, modified, and type fields. The [] operator
selects each object in the array, and the {} operator creates a new object with the desired fields.
jq '[.[] | {
id: .id,
name: .name,
query: .query,
message: .message,
created: .created,
creator: .creator.email,
modified: .modified,
type: .type
}]' datadog_monitors.json
Extract the recipients from DataDog monitor TSV:
cut -f 4 datadog_monitors.txt | grep '@' | sed -e 's/[^@]*//' | sort | uniq
AWS
Query Database Instances
Get basic instance information and filtering by security group. The file rds_instances.json was created by running
this command:
aws rds describe-db-instances
This query filters a JSON file containing AWS RDS instance data to select only those instances that have a specific VPC
security group. For each selected instance, it extracts a subset of the fields, including the DBInstanceIdentifier,
Engine, Endpoint.Address, Endpoint.Port, and VpcSecurityGroups[].VpcSecurityGroupId fields.
jq '[.DBInstances[] |
select(.VpcSecurityGroups[].VpcSecurityGroupId == "sg-731b5d16") |
{
db_id: .DBInstanceIdentifier,
engine: .Engine,
ep_addr: .Endpoint.Address,
ep_port: .Endpoint.Port,
sec_grps: [.VpcSecurityGroups[].VpcSecurityGroupId]
}
]' rds_instances.json
The same above but output as CSV rather than JSON:
jq -r '.DBInstances[] |
select(.VpcSecurityGroups[].VpcSecurityGroupId == "sg-731b5d16") |
[.DBInstanceIdentifier, .Engine, .Endpoint.Address, .Endpoint.Port] |
@csv' rds_instances.json
And finally doing it all in one command:
aws rds describe-db-instances | \
jq -r '.DBInstances[] |
select(.VpcSecurityGroups[].VpcSecurityGroupId == "sg-731b5d16") |
[.DBInstanceIdentifier, .Engine, .Endpoint.Address, .Endpoint.Port] |
@csv'
Query Route 53
The following is an example Route 53 JSON response from an AWS CLI request to get all records for a hosted zone. The
example file will be referred to as route53.json and was generated using a command like:
aws route53 list-resource-record-sets --hosted-zone-id ABC123 > route53.json
This is example output:
{
"ResourceRecordSets": [
{
"Name": "example.com.",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "10.0.0.1"
},
{
"Value": "10.0.0.2"
}
]
},
{
"Name": "www.example.com.",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "example.com"
}
]
},
{
"Name": "alias.example.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "d1234.cloudfront.net",
"EvaluateTargetHealth": false
}
},
{
"Name": "example.com.",
"Type": "NS",
"TTL": 172800,
"ResourceRecords": [
{
"Value": "ns-1234.awsdns-12.org."
},
{
"Value": "ns-5678.awsdns-56.co.uk."
}
]
},
{
"Name": "example.com.",
"Type": "SOA",
"TTL": 900,
"ResourceRecords": [
{
"Value": "ns-1234.awsdns-12.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"
}
]
},
{
"Name": "mail.example.com.",
"Type": "MX",
"TTL": 300,
"ResourceRecords": [
{
"Value": "10 mail.example.com."
},
{
"Value": "20 alt1.mail.example.com."
},
{
"Value": "30 alt2.mail.example.com."
}
]
},
{
"Name": "example.com.",
"Type": "TXT",
"TTL": 300,
"ResourceRecords": [
{
"Value": "\"v=spf1 include:_spf.google.com ~all\""
}
]
}
]
}
The following query takes the Route 53 example JSON file, selects all the ResourceRecordSet objects in the file,
filters out records of type NS and SOA, and extracts the Name, Type, and Value fields of each record. If the
record has multiple Value fields, they are concatenated into a single comma-separated string. The resulting output is
formatted as a TSV string.
jq -r '.ResourceRecordSets[] |
select(.Type != "NS" and .Type != "SOA") |
[.Name, .Type,
if .ResourceRecords
then (.ResourceRecords | map(.Value) | join(","))
else .AliasTarget.DNSName
end] |
@tsv' route53.json
This is the output:
example.com. A 10.0.0.1,10.0.0.2
www.example.com. CNAME example.com
alias.example.com. A d1234.cloudfront.net
mail.example.com. MX 10 mail.example.com.,20 alt1.mail.example.com.,30 alt2.mail.example.com.
example.com. TXT "v=spf1 include:_spf.google.com ~all"
Here's what the query is doing, step by step:
.ResourceRecordSets[]- This part of the query selects all theResourceRecordSetsobjects in the JSON file and iterates over them.select(.Type != "NS" and .Type != "SOA")- This part of the query filters out records of typeNSandSOAfrom the output. Theselect()function takes a boolean expression as its argument, and returns only the elements of the array that evaluate totrue. In this case, the expression(.Type != "NS" and .Type != "SOA")evaluates totruefor all records that are not of typeNSorSOA.[.Name, .Type, if .ResourceRecords then (.ResourceRecords | map(.Value) | join(",")) else .AliasTarget.DNSName end]- This part of the query creates an array that includes theName,Type, andValuefields of eachResourceRecordSetobject. If the record hasResourceRecords, the query maps theValuefield of eachResourceRecordobject to an array of strings, and then joins them into a comma-separated string using thejoin()function. If the record has anAliasTarget, the query extracts theDNSNamefield under theAliasTargetobject. The resulting array contains theName,Type, andValuefields of the record.@tsv- This part of the query formats the output as a tab-separated value (TSV) string. The fields in the array created in step 3 are separated by tabs rather than commas.-r- This option tells jq to output the result as raw text rather than JSON.