"green"
If we need to retrieve multiple keys, we can separate them using a comma:
jq '.fruit.color,.fruit.price' fruit.json
This results in an output containing both property values:
"green"
Note that if one of the properties has spaces or special characters, we need to wrap the property name in quotes when accessing it from the jq command:
echo '{ "with space": "hello" }' | jq '."with space"'
4. JSON Arrays
Let’s now look at how we can work with arrays in JSON data. We typically use arrays to represent a list of items. And as in many programming languages, we use square brackets to denote the start and end of an array.
4.1. Iteration
We’ll start with a basic example to demonstrate how to iterate over an array:
echo '["x","y","z"]' | jq '.[]'
Here, we see the object value iterator operator .[] in use, which will print out each item in the array on a separate line:
Now let’s imagine we want to represent a list of fruit in a JSON document:
"name": "apple",
"color": "green",
"price": 1.2
"name": "banana",
"color": "yellow",
"price": 0.5
"name": "kiwi",
"color": "green",
"price": 1.25
Each item in the array is an object that represents a fruit.
Let’s see how to extract the name of each fruit from each object in the array:
jq '.[] | .name' fruits.json
First, we iterate over the array using .[]. Then we can pass each object in the array to the next filter in the command using a pipe |. The last step is to output the name field from each object using .name:
"apple"
"banana"
"kiwi"
We can also use a slightly more concise version and access the property directly on each object in the array:
jq '.[].name' fruits.json
4.2. Accessing by Index
Of course, as with all arrays, we can access one of the items in the array directly by passing the index:
jq '.[1].price' fruits.json
4.3. Slicing
Finally, jq also supports slicing of arrays, another powerful feature. This is particularly useful when we need to return a subarray of an array.
Again, let’s see this using a simple array of numbers:
echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[6:9]'
The result will be a new array with a length of 3, containing the elements from index 6 (inclusive) to index 9 (exclusive):
It’s also possible to omit one of the indexes when using the slicing functionality:
echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[:6]' | jq '.[-2:]'
Since we specified only the second argument in .[:6], the slice will start from the beginning of the array and run up until index 6. It’s the same as doing .[0:6].
The second slicing operation has a negative argument, which denotes in this case that it counts backward from the end of the array.
Note the subtle difference in the second slice — we pass the index as the first argument. This means we will start two indexes from the end (-2), and since the second argument is empty, it will run until the end of the array.
This gives us the following output:
5. Using Functions
jq has many powerful built-in functions that we can use to perform a variety of useful operations. Let’s take a look at some of them now.
5.1. Getting Keys
Sometimes, we may want to get the keys of an object as an array instead of the values.
We can do this using the keys function:
jq '.fruit | keys' fruit.json
This gives us the keys sorted alphabetically:
"color",
"name",
"price"
5.2. Returning the Length
Another handy function for arrays and objects is the length function.
We can use this function to return the array’s length or the number of properties on an object:
jq '.fruit | length' fruit.json
Here, we get “3” since the fruit object has three properties.
We can even use the length function on string values as well:
jq '.fruit.name | length' fruit.json
We would see “5” as the resulting output since the fruit name property has five characters: “apple”.
5.3. Mapping Values
The map function is a powerful function we can use to apply a filter or function to an array:
jq 'map(has("name"))' fruits.json
In this example, we’re applying the has function to each item in the array and looking to see if there is a name property. In our simple fruits JSON, we get true in each result item.
We can also use the map function to apply operations to the elements in an array.
Let’s imagine we want to increase the price of each fruit:
jq 'map(.price+2)' fruits.json
This gives us a new array with each price incremented:
5.4. Min and Max
If we need to find the minimum or maximum element of an input array, we can utilize the min and max functions:
jq '[.[].price] | min' fruits.json
Likewise, we can also find the most expensive fruit in our JSON document:
jq '[.[].price] | max' fruits.json
Note that in these two examples, we’ve constructed a new array, using [] around the array iteration. This contains only the prices before we pass this new list to the min or max function.
5.5. Selecting Values
The select function is another impressive utility that we can use for querying JSON.
We can think of it as a bit like a simple version of XPath for JSON:
jq '.[] | select(.price>0.5)' fruits.json
This selects all the fruit with a price greater than 0.5.
Likewise, we can also make selections based on the value of a property:
jq '.[] | select(.color=="yellow")' fruits.json
We can even combine conditions to build up complex selections:
jq '.[] | select(.color=="yellow" and .price>=0.5)' fruits.json
This will give us all yellow fruit matching a given price condition:
"name": "banana",
"color": "yellow",
"price": 0.5
5.6. Support for Regular Expressions
Next, we’re going to look at the test function, which enables us to test if an input matches against a given regular expression:
jq '.[] | select(.name|test("^a.")) | .price' fruits.json
Simply put, we want to output the price of all the fruit whose name starts with the letter “a”.
5.7. Finding Unique Values
One common use case is to be able to see unique occurrences of a particular value within an array or remove duplicates.
Let’s see how many unique colors we have in our fruits JSON document:
jq 'map(.color) | unique' fruits.json
We use the map function to create a new array containing only colors. Then we pass each color in the new array to the unique function using a pipe |.
This gives us an array with two distinct fruit colors:
"green",
"yellow"
5.8. Deleting Keys From JSON
We’ll also sometimes want to remove a key and corresponding value from JSON objects.
For this, jq provides the del function:
jq 'del(.fruit.name)' fruit.json
This outputs the fruit object without the deleted key:
"fruit": {
"color": "green",
"price": 1.2
Frequently when working with data structures such as JSON, we might want to transform one data structure into another. This can be useful while working with large JSON structures when we are only interested in several properties or values.
In this example, we’ll use some Wikipedia JSON that describes a list of page entries:
"query": {
"pages": [
"21721040": {
"pageid": 21721040,
"ns": 0,
"title": "Stack Overflow",
"extract": "Some interesting text about Stack Overflow"
"21721041": {
"pageid": 21721041,
"ns": 0,
"title": "Baeldung",
"extract": "A great place to learn about Java"
We’re only really interested in the title and extract of each page entry.
So, let’s see how we can transform this document:
jq '.query.pages | [.[] | map(.) | .[] | {page_title: .title, page_description: .extract}]' wikipedia.json
We’ll take a look at the command in more detail to understand it properly:
First, we begin by accessing the pages array and passing that array into the next filter in the command via a pipe.
Then we iterate over this array and pass each object inside the pages array to the map function, where we simply create a new array with the contents of each object.
Next, we iterate over this array and for each item create an object containing the two keys page_title and page_description.
The .title and .extract references are used to populate the two new keys.
This gives us a new, lean JSON structure:
"page_title": "Stack Overflow",
"page_description": "Some interesting text about Stack Overflow"
"page_title": "Baeldung",
"page_description": "A great place to learn about Java"
7. Conclusion
In this in-depth article, we covered some of the basic capabilities that jq provides for processing and manipulating JSON via the command line.
First, we looked at some of the essential filters jq offers and how they can be used as the building blocks for more complex operations. Then we saw how to use a number of built-in functions that come bundled with jq.
We concluded with a complex example showing how to transform one JSON document into another.
Of course, be sure to check out the excellent cookbook for more interesting examples, and as always, the full source code of the article is available on GitHub.