JQ ဆိုတာ JSON data တွေကို command line မှာ process လုပ်ဖို့အသုံးပြုတဲ့ command-line JSON processor တစ်ခုဖြစ်ပါတယ်။ JSON data ကို query, filter, transform, နှင့် manipulate လုပ်ဖို့အတွက် အထူးသင့်တော်ပါတယ်။ JQ ဟာ lightweight ဖြစ်ပြီး Linux, macOS, Windows အပါအဝင် OS အများစုမှာ run လုပ်နိုင်ပါတယ်။
Functions of JQ
JQ command line tool ဖြင့် အောက်ပါ functions တွေကို စွမ်းဆောင်နိုင်သည်။
JSON Parsing: JSON data ကို parse လုပ်ပြီး tree structure အနေနဲ့ ကိုင်တွယ်နိုင်စေတယ်။
Filtering: JSON data ထဲက လိုအပ်တဲ့ fields, objects, အဖြစ် filter လုပ်နိုင်တယ်။
Transformation: JSON data ကို one form to another form သို့ ပြောင်းပေးနိုင်တယ်။
Formatting: JSON data ကို human-readable ဖြစ်အောင် format ပြုလုပ်ခြင်းနှင့် pretty-print ဖြစ်အောင် display ပြသပေးနိုင်တယ်။
Composing: Multiple filters တွေကို combine လုပ်ပြီး complex queries တွေရေးနိုင်တယ်။
Challenges in Handling JSON from the Command Line
JSON ကို modern API တွေနှင့် data services အများစုတွင် အသုံးပြုလေ့ရှိသော popular ဖြစ်သည့် structured data format တစ်မျိုးဖြစ်သည်။ ၎င်းသည် lightweight design ဖြစ်သည့် အပြင် JavaScript နှင့် တွဲဖက်အသုံးပြုနိုင်သောကြောင့် online applications တွေမှာ အများဆုံးတွေ့ရသည်။
Bash ကဲ့သို့သော shell များတွင် JSON ကို natively understand and manipulate မပြုလုပ်နိုင်ပါ။ ဒါကြောင့် command line မှတဆင့် JSON ကို ကိုင်တွယ်ရသည်မှာ အချိန်စားနိုင်ပါသည်။
For example: sed နှင့် grep ကဲ့သို့သော text manipulation tool များကို အသုံးပြုရခြင်းကြောင့် ဖြစ်သည်။
How to Install jq
1. Linux
Debian/Ubuntu:
sudo apt install jq
Fedora:
sudo dnf install jq
Arch:
sudo pacman -S jq
Manual: Download binary, make it executable, and move to
/usr/local/bin
.
2. macOS
Use Homebrew:
brew install jq
3. Windows
Chocolatey:
choco install jq
Manual: Download from GitHub and add to PATH.
4. Docker
Run
jq
inside a container:docker run --rm -i stedolan/jq jq
5. Verify Installation
If the installation was successful, the console will display the version, usage examples, and other information.
Working With Simple Filters
jq
သည် JSON data တွင် filter များကို အသုံးပြုသည့် နည်းလမ်းဖြင့် အလုပ်လုပ်သည်။ Filter တစ်ခုစီသည် input ကို လက်ခံပြီး JSON ကို output အဖြစ် ပြန်ပေးသည်။ Preconfigured filter များစွာရှိပြီး၊ pipeline များဖြင့် ပေါင်းစပ်ကာ JSON data တွင် ရိုးရှင်းသည့်အပြင် အဆင့်မြင့်လုပ်ဆောင်မှုများကို မြန်ဆန်စွာ ပြုလုပ်နိုင်သည်။
Prettify JSON
jq
ရဲ့ basic features တွေထဲက တစ်ခုဖြစ်တဲ့ identity filter ကို ကြည့်ကျရအောင် …
echo '{"fruit":{"name":"apple","color":"red","price":3.0}}' | jq '.'
ကျွန်ုပ်တို့သည် အသီးတစ်ခု၏ အမည်၊ အရောင်နှင့် စျေးနှုန်းကို ဖော်ပြထားသော ရိုးရှင်းသော JSON object ကို echo ပြုလုပ်ပြီး jq command သို့ pipe ထည့်ပေးပါသည်။ Filter ‘.’ သည် identity filter ဖြစ်ပြီး ဒေတာကို မပြောင်းလဲဘဲ ထားပါသည်။ jq သည် input ကို စီစစ်သောအခါ အတိအကျ တူညီသော JSON ကို output ထုတ်ပေးပါသည်၊ သို့သော် jq သည် JSON output ကို ပိုမိုဖတ်ရှုရလွယ်ကူအောင် အလိုအလျောက် "pretty-print" သို့မဟုတ် ဖော်မတ်လုပ်ပေးသည်။
JSON ဖိုင်တစ်ခုမှာ ဒီ filter ကို direct တန်း အသုံးပြုနိုင်ပါတယ်။
#To create fruit.json file as below.
echo '{"fruit":{"name":"apple","color":"red","price":3.0}}' > fruit.json
jq '.' fruit.json
The ability of prettify JSON သည် API များထံမှ data များကို ရယူရာတွင် clear and readable ပုံစံဖြင့် ပြသရန် အထူးအသုံးဝင်သည်။ curl
ကိုအသုံးပြုပြီး simple API call တစ်ခုကို ခေါ်ကြည့်ကျရအောင်
curl http://api.open-notify.org/iss-now.json | jq '.'
၎င်းသည် နိုင်ငံတကာ အာကာသစခန်း (ISS) ၏ လက်ရှိအနေအထားကို ပြသသည့် JSON response ကို ပေးသည်။
Accessing Properties
JSON တည်ဆောက်ပုံအတွင်းရှိ သတ်မှတ်ထားတဲ့ values တွေကို .field
operator လို့ခေါ်တဲ့ filter ကိုအသုံးပြုပြီး jq ဖြင့် ရယူနိုင်ပါတယ်။ ဒီ operator က JSON object ရဲ့ specific property or field တစ်ခုရဲ့ value ကို ရယူနိုင်စေပါတယ်။
fruit.json ရဲ့ example ကို ဆက်လက် အသုံးပြုပြီး ဒီအရာကို ကြည့်ကျရအောင် …
jq '.fruit' fruit.json
ဒီနေရာမှာ ကျွန်တော်တို့ fruit
property ကို ရွေးပြီး၊ အဲဒီ property အောက်မှာပါတဲ့ အရာတွေကို တစ်ခုလုံး ပြသဖို့ လုပ်ပါတယ်။ fruit
ဟာ အဓိက key ဖြစ်ပြီး၊ အဲ့ဒီ key အောက်မှာ name, color, price လို့ခေါ်တဲ့ အချက်အလက်တွေ (children) ပါပါတယ်။
{
"name": "apple",
"color": "red",
"price": 3.0
}
ကျွန်တော်တို့ property တွေကို အဆင့်လိုက်ဆက်ပြီး ရှာဖွေသုံးနိုင်ပါတယ်။ ဒါကိုဆိုလိုတာက JSON အထဲမှာ အတွင်းပိုင်းရှိ (nested) အချက်အလက်တွေကို ရယူနိုင်တာပါ။ ဥပမာအားဖြင့် fruit
property ရဲ့ name
ကို ရယူချင်ရင် .fruit.name
လို့ ရိုက်လိုက်ရုံနဲ့ ရနိုင်ပါတယ်။
jq '.fruit.color' fruit.json
jq '.fruit.nmae' fruit.json
jq '.fruit.price' fruit.json
JSON မှာ key တစ်ခုထက် ပိုပြီး ရယူချင်ရင် key တွေကို comma နဲ့ ခွဲပြီး ရယူနိုင်ပါတယ်။ ဥပမာ fruit
အောက်မှာ color
နဲ့ price
တိုင်းကို ရယူချင်ရင် .fruit.color, .fruit.price
လို့ ရိုက်နိုင်ပါတယ်။ Comma သုံးတာနဲ့ key နှစ်ခုလုံးရမှာ ဖြစ်ပါတယ်။
jq '.fruit.color,.fruit.price' fruit.json
အကယ်၍ JSON ထဲမှာ space ပါတဲ့ key ရှိခဲ့မယ်ဆိုရင်၊ အဲ့ဒီ key ကို ရိုးရိုး key တစ်ခုလို .key
နဲ့ ချိတ်မရနိုင်ပါဘူး။ ဥပမာအားဖြင့် with space
ဆိုတဲ့ key မှာ space တစ်ခု ပါပါတယ်။ အဲ့ဒီလို key ကို jq
နဲ့ရယူချင်ရင်၊ အဲ့ဒီ key ကို double quotes (“”) အတွင်း ထည့်သုံးပေးရပါမယ်။
ပုံမှန် key တစ်ခုကို .key
ဆိုပြီး ရယူနိုင်သလို၊ space ပါတဲ့ key ကို ."with space"
ဆိုပြီး double quotes နဲ့ ရိုက်ပြီးသုံးရပါတယ်။
ဉပမာအားဖြင့် with_space.json
ဖိုင်မှာ အောက်ပါအတိုင်း content ရှိခဲ့မယ်ဆိုပါစို့ …
{
"regularKey": "value1",
"with space": "value2",
"123startWithNumber": "value3"
}
jq
ကို အသုံးပြု၍ အဲ့ဒီ property တွေကို ရယူဖို့ …
aungaung@drlinuxer-x14:~$ jq '."regularKey"' with_space.json
"value1"
aungaung@drlinuxer-x14:~$ jq '."with space"' with_space.json
"value2"
aungaung@drlinuxer-x14:~$ jq '."123startWithNumber"' with_space.json
"value3"
What is a JSON Array?
JSON Array ဆိုသည်မှာ JSON တွင် အချက်အလက်များ၏ စာရင်းကို ကိုယ်စားပြုသည့် data structure တစ်ခုဖြစ်သည်။ Array ထဲတွင် ပါရှိသည့် အချက်အလက်များသည် strings၊ numbers၊ objects၊ arrays၊ booleans၊ သို့မဟုတ် null
အပါအဝင် JSON မှာ အတည်ပြုထားသည့် data အမျိုးအစား မည်သည့်အရာမဆို ဖြစ်နိုင်ပါသည်။
JSON array များကို []
(square brackets) ဖြင့် ကန့်သတ်ထားပြီး၊ array အတွင်းရှိ item များကို comma (,) ဖြင့် ခွဲထားသည်။
JSON array ကို အမျိုးမျိုးသော data အမျိုးအစားတွေနဲ့ ဖော်ပြထားပါတယ်။
- Strings Array:
["apple", "banana", "cherry"]
- Numbers Array:
[1, 2, 3, 4.5, 6.78]
- Objects Array:
[
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30}
]
- Nested Arrays:
[[1, 2, 3], ["a", "b", "c"], [true, false]]
- Booleans Array:
[true, false, true, false]
- Nulls Array:
[null, null, "example", 42]
ဒီအကြောင်းအရာတွေက JSON array များကို မတူညီတဲ့ data type မျိုးစုံနဲ့ ဘယ်လိုဖွဲ့စည်းနိုင်တယ်ဆိုတာကို ပြသပေးပါတယ်။
jq
ကိုသုံးပြီး အထက်ဖော်ပြခဲ့သည့် JSON array များကို ရယူရန် နှင့် စိစစ်ရန် အတွက် အောက်ပါနည်းလမ်းများကို အသုံးပြုနိုင်ပါတယ်။
Strings Array:
echo '["apple", "banana", "cherry"]' | jq '.[1]'
Output:
"banana"
(Index1
မှာရှိတဲ့ item ကို ရယူရန်)Numbers Array:
echo '[1, 2, 3, 4.5, 6.78]' | jq '.[3]'
Output:
4.5
(Index3
မှာရှိတဲ့ number ကို ရယူရန်)Objects Array:
echo '[{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]' | jq '.[0].name'
Output:
"Alice"
(Index0
မှာရှိတဲ့ object ရဲ့name
property ကို ရယူရန်)Nested Arrays:
echo '[[1, 2, 3], ["a", "b", "c"], [true, false]]' | jq '.[1][2]'
Output:
"c"
(Index1
ရဲ့ nested array ထဲက Index2
ကို ရယူရန်)Booleans Array:
echo '[true, false, true, false]' | jq '.[2]'
Output:
true
(Index2
မှာရှိတဲ့ boolean value ကို ရယူရန်)Nulls Array:
echo '[null, null, "example", 42]' | jq '.[2]'
Output:
"example"
(Index2
မှာရှိတဲ့ string ကို ရယူရန်)
ဒါ့အပြင် jq
ကို အသုံးပြု၍ array ရဲ့ items များကို filter လုပ်ခြင်း၊ မိမိလိုအပ်သည့် conditions တွေ ဖြင့် ပြင်ဆင်ခြင်း စသဖြင့် ပိုမိုရှုပ်ထွေးတဲ့ လုပ်ဆောင်ချက်များကိုလည်း လုပ်ဆောင်နိုင်ပါတယ်။
Iterating Over a JSON Array
JSON array ထဲက item တစ်ခုချင်းစီကို loop ဖြင့် iterate (ပြန်လှည့်) သွားရန် jq
ကို အသုံးပြုနိုင်ပါတယ်။ ဒါက JSON array ထဲမှာ item အပေါင်းကို အသီးအသီး ရယူပြီး လုပ်ဆောင်မှုတစ်ခုခု ပြုလုပ်ချင်တဲ့အခါအသုံးဝင်ပါတယ်။
ဥပမာအားဖြင့် JSON array ကို iterating လုပ်ပုံကို ပြသထားပါတယ်။
Iterating Over a JSON Array
Example 1: Iterating Over a Strings Array
echo '["apple", "banana", "cherry"]' | jq '.[]'
Output:
"apple"
"banana"
"cherry"
Explanation: jq '.[]'
က JSON array ထဲက item တစ်ခုချင်းစီကို ရယူပြီး အစီအစဉ်အတိုင်း ပြသပေးပါတယ်။
Example 2: Iterating Over an Array of Numbers
echo '[1, 2, 3, 4.5, 6.78]' | jq '.[]'
Output:
1
2
3
4.5
6.78
Explanation: .[]
က array ထဲက number တစ်ခုချင်းစီကို ပြသရန် အသုံးပြုသည်။
Example 3: Iterating Over an Array of Objects
echo '[{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]' | jq '.[] | .name'
Output:
"Alice"
"Bob"
Explanation: .[]
က object တစ်ခုချင်းစီကို iterate လုပ်ပြီး၊ | .name
ကတော့ object ထဲက name
property ကိုပြသဖို့ သတ်မှတ်ထားခြင်း ဖြစ်ပါတယ်။
Example 4: Iterating Over Nested Arrays
echo '[[1, 2, 3], ["a", "b", "c"], [true, false]]' | jq '.[] | .[1]'
Output:
2
"b"
false
Explanation: .[] | .[1]
က array တစ်ခုချင်းစီကို iterate လုပ်ပြီး၊ array item တစ်ခုချင်းစီမှ index 1
ကို ရယူသည်။
Iterating Over with Additional Processing
echo '[true, false, null, "example"]' | jq '.[] | select(. != null)'
Output:
true
false
"example"
Explanation: select(. != null)
က null
မဟုတ်တဲ့ items တွေကိုသာ ရယူပြသရန် filter လုပ်ထားခြင်း ဖြစ်ပါတယ်။
ဒီလိုနည်းလမ်းတွေက JSON array ထဲမှာ item တွေကို loop ဖွင့်ပြီး iterate လုပ်ရုံသာမက၊ ထိန်းချုပ်နိုင်တဲ့ logic တွေကိုပါ ထည့်သွင်းသုံးစွဲနိုင်ပါတယ်။
One of the most common operations when working with JSON arrays is iterating over the items in the array. To do this in jq
, we use the iterator operator .[]
. This operator will iterate over each element in the array and return each one individually.
For example, if you have the array ["x", "y", "z"]
, you can iterate over it with:
echo '["x","y","z"]' | jq '.[]'
The .[]
operator iterates over each element of the array, and jq
prints each item on a separate line.
"x"
"y"
"z"
Working with Arrays of Objects
Let’s say we have an array where each element is an object instead of a simple value. For example, imagine we have an array of fruit objects, each containing information like the name, color, and price of a fruit:
vi fruit2.json
[
{
"name": "apple",
"color": "red",
"price": 3.0
},
{
"name": "banana",
"color": "yellow",
"price": 2.0
},
{
"name": "kiwi",
"color": "green",
"price": 1.5
}
]
Each item in the array is an object with properties like name
, color
, and price
.
Extracting Specific Values
If we want to extract the name of each fruit in the array, we would use the .[]
operator to iterate over the array and then access the name
property for each object. Here's the jq
command to do that:
jq '.[] | .name' fruit2.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:
A More Concise Version
We can simplify this even further by combining both operations into one:
jq '.[].name' fruits.json
Accessing Array Items by Index in jq
In jq
, you can access individual elements from an array by using indices (positions) in the array, similar to how you'd access an array element in most programming languages.
Example: Accessing by Index
Let’s assume we have the following array of fruit objects:
jq '.[0].price' fruit2.json
jq '.[1].price' fruit2.json
jq '.[2].price' fruit2.json
Slicing Arrays in jq
Slicing is a powerful feature that allows you to extract subarrays from an array. This is useful when you need only a portion of the array rather than the entire set of elements.
Example: Slicing an Array
Consider the following array of numbers:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Let’s say you want to get a subarray of elements starting from index 6
(inclusive) to index 9
(exclusive). You can use slicing as follows:
echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[6:9]'
Output:
[7, 8, 9]
.[6:9]
: This slice starts at index6
(inclusive) and ends at index9
(exclusive). So, it includes the elements at indices6
,7
, and8
, which are7
,8
, and9
.
Omitting Indices in Slicing
In jq
, you can also omit one or both of the indices in the slice to define a range starting from the beginning or going until the end of the array.
- Slice from the beginning to a specific index:
echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[:6]'
Output:
[1, 2, 3, 4, 5, 6]
[:6]
: This slice means "start from the beginning" (index0
) and go up to but not including index6
. It returns the elements1, 2, 3, 4, 5, 6
.
- Slice from a negative index to the end:
echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[-2:]'
Output:
[9, 10]
.[-2:]
: This slice starts from the second-to-last element (-2
) and includes all elements up to the end of the array.The negative index means it counts backwards from the end of the array. So,
-2
refers to the element9
, and:
means "continue until the end."
Combining Slices
You can also combine slices for more complex extraction.
For example:
echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[:6] | .[-2:]'
Output:
[5, 6]
Here’s what happens:
[:6]
: This slice gives us the first 6 elements:[1, 2, 3, 4, 5, 6]
..[-2:]
: The second slice (.[-2:]
) selects the last two elements from that result, which are[5, 6]
.
Summary of Key Concepts:
Accessing by Index: You can directly access an element in an array by specifying its index, using
.[index]
.- For example,
.[1].price
accesses the second item in an array and retrieves theprice
field.
- For example,
Array Slicing:
jq
supports array slicing, which allows you to extract subarrays by specifying a start and end index in the form.[start:end]
.- You can omit the start (
[:end]
) or end ([start:]
) to slice from the beginning or until the end, respectively.
- You can omit the start (
Negative Indices: Negative indices (like
-2
) count backwards from the end of the array, with-1
being the last element.
These features give you flexible ways to manipulate and access parts of arrays within JSON data using jq
.
Using Functions in jq
jq
provides many powerful built-in functions that allow you to manipulate, transform, and query JSON data efficiently. Here’s a breakdown of some useful functions:
1. Getting Keys
Sometimes, you might want to get just the keys of an object in JSON, rather than its values. You can use the keys
function for this:
jq '.fruit | keys' fruit.json
This gives us the keys sorted alphabetically:
[
"color",
"name",
"price"
]
2. Returning the Length
You can use the length
function to get the length of an array or the number of properties in an object:
On an Object (getting the number of properties):
jq '.fruit | length' fruit.json
Output:
3
This shows that the
fruit
object has 3 properties (color
,name
, andprice
).On a String (getting the length of a string):
jq '.fruit.name | length' fruit.json
Output:
5
This shows that the
name
of the fruit ("apple") has 5 characters.
3. Mapping Values with map
The map
function applies a filter or transformation to each element in an array. For example, you can use it to check for the presence of a property in each object:
jq 'map(has("name"))' fruit2.json
This will check if the
name
property exists in each object in the array. If it does, it will returntrue
; otherwise,false
.Output:
[ true, true, true ]
You can also use map
to apply a transformation to the values in the array, such as modifying the price
:
jq 'map(.price + 2)' fruit2.json
This adds
2
to the price of each fruit.Output:
[ 5, 4, 3.5 ]
4. Min and Max Functions
To find the minimum or maximum value in an array, you can use the min
and max
functions:
Minimum Price:
jq '[.[].price] | min' fruit2.json
Output:
1.5
Maximum Price:
jq '[.[].price] | max' fruit2.json
Output:
3.0
In both cases, we construct a new array of just the price
values using [.[].price]
before applying min
or max
.
5. Selecting Values with select
The select
function allows you to filter elements in an array based on certain conditions, similar to how XPath
works for XML.
For example, you can select fruits with a price greater than 1.5
:
jq '.[] | select(.price > 1.5)' fruit2.json
This selects all fruits with a price greater than
1.5
.Output:
{ "name": "apple", "color": "red", "price": 3.0 } { "name": "banana", "color": "yellow", "price": 2.0 }
You can also combine conditions, like selecting fruits that are yellow and have a price greater than or equal to 1.5:
jq '.[] | select(.color == "yellow" and .price >= 1.5)' fruit2.json
Output:
{
"name": "banana",
"color": "yellow",
"price": 2.0
}
6. Using Regular Expressions with test
The test
function allows you to test if a string matches a regular expression. For example, to select fruits whose name
starts with the letter "a":
jq '.[] | select(.name | test("^a.")) | .price' fruit2.json
This filters fruits where the
name
starts with "a" and returns theirprice
.Output:
3.0
7. Finding Unique Values with unique
To find unique values in an array, you can use the unique
function. For example, to find all unique colors in the fruits.json
:
jq 'map(.color) | unique' fruit2.json
The
map(.color)
part creates a new array with just the color values.The
unique
function then removes duplicates.Output:
[ "green", "red", "yellow" ]
8. Deleting Keys with del
The del
function allows you to remove a key from a JSON object. For example, if you want to delete the name
property from the fruit
object:
jq 'del(.fruit.name)' fruit.json
This will remove the
name
key and its corresponding value.Output:
{ "fruit": { "color": "red", "price": 3.0 } }
9. Transforming JSON Structure
You can also transform the structure of your JSON. For example, suppose you have JSON data from Wikipedia pages, and you want to extract only the title
and extract
fields for each page:
vi transform.json
{
"query": {
"pages": [
{
"21721050": {
"pageid": 21721050,
"ns": 0,
"title": "Stack Overflow",
"extract": "Some interesting text about Stack Overflow"
}
},
{
"21721051": {
"pageid": 21721051,
"ns": 0,
"title": "Github",
"extract": "Build software better, together"
}
}
]
}
}
To transform this JSON into a new structure containing only the title
and extract
fields:
jq '.query.pages | [.[] | map(.) | .[] | {page_title: .title, page_description: .extract}]' transform.json
This creates a new array of objects with just the
title
andextract
properties.Output:
[ { "page_title": "Stack Overflow", "page_description": "Some interesting text about Stack Overflow" }, { "page_title": "Github", "page_description": "Build software better, together" } ]
Summary
These are just a few examples of the many powerful functions available in jq
. These functions enable you to:
Extract keys and values.
Perform filtering and selection.
Modify arrays and objects.
Apply transformations to JSON data.
By combining these functions, you can perform complex operations and data manipulations directly on JSON, making jq
a powerful tool for working with structured data.