How to extract value from json contained in a variable using jq in bash
You may use this:
json_val='{"code":"lyz1To6ZTWClDHSiaeXyxg","redirect_to":"http://example.com/client-redirect-uri?code=lyz1To6ZTWClDHSiaeXyxg"}'
code_val=$(jq -r '.code' <<< "$json_val")
echo "$code_val"
lyz1To6ZTWClDHSiaeXyxg
Note following changes:
- Wrap complete json string in single quotes
- use of
$(...)
for command substitution - Use of
<<<
(here-string) to avoid a sub-shell creation
PS: If you're getting json
text from a curl command and want to store multiple fields in shell variables then use:
read -r code_val redirect_to < <(curl ... | jq -r '.code + "\t" + .redirect_to')
Where ...
is your curl command.
Extract value of json-like variable in bash
If
echo $CLUSTER
gives you
{ "ClusterId": "j-9YWMBYN98LN7" }
then
ID=$(awk 'BEGIN{FS="\""}{print $4}' <<< "${CLUSTER}")
should do it.
echo "$ID"
j-9YWMBYN98LN7
Retrieving value from JSON object in bash using JQ
NAME=$(jq -r '.ConfigurationRecorders[].name' <<<"$CONFIG_RECORDER")
<<<
is known as here-string
.
-r
removes the quotes in the result.
[]
in the jq query is necessary as ConfigurationRecorders is a JSON array.
$( … )
is just an other form of command substitution than backticks. I prefer this one as it is more readable to me.
Extract JSON value to shell variable using jq
In order to handle all values properly, you need to use the declare
command to incorporate the output of jq
into an array assignment.
Here's some input with some corner cases to worry about: whitespace, a newline, and a glob character.
$ cat input.json
[
{"id":10,
"list_file":[
"/var/a b.txt",
"/dev/c\nd.txt",
"*"]}
]
A jq
command that extracts and outputs properly quoted strings for use by the shell:
$ $ jq -r '.[] | .list_file[] | @sh' input.json
'/var/a b.txt'
'/dev/c
d.txt'
'*'
And a shell command that can make use of the output:
$ declare -a "x=($(jq -r '.[] | .list_file[] | @sh' input.json))"
Proof that it worked properly:
$ printf '==%s==\n' "${x[@]}"
==/var/a b.txt==
==/dev/c
d.txt==
==*==
Extract values from JSON objects and assign them to shell variables in a loop
You can output each email-ID pair as a comma separated list from JQ, and use read them into variables in a while loop like so:
while IFS=',' read -r email id; do
echo "$email"
echo "$id"
done <<EOF
$(jq -r '.values[] | "\(.email),\(.id)"' file)
EOF
select specific values from json & convert into bash variables
If instead of trying to extract variable names from the JSON, you populate an associate array with the names as keys, it's pretty straightforward.
#!/usr/bin/env bash
declare -A sauces
while IFS=$'\001' read -r name value; do
sauces[$name]=$value
done < <(jq -r '.env_vars[] | "\(.name)\u0001\(.value)"' saucy.json)
for name in "${!sauces[@]}"; do
echo "$name is ${sauces[$name]}"
done
prints out
SAUCE_VALUE is sauceValue
SAUCE_KEY is sauceKey
Using jq to fetch key value from json output
You need to combine filters by means of |
operator:
$ jq -r '.[] | .[] | .name' test.json
rhel6.6
rhel7
The first .[]
fetches repositories
array. The next .[]
fetches all the items of the repositories
array. Finally, .name
extracts properties from the array items(objects).
Note, the first .[]
works on object because it is a documented feature:
.[]
If you use the .[index] syntax, but omit the index entirely, it
will return all of the elements of an array...
You can also use this on an object, and it will return all the
values of the object.
Parse JSON data in variables using JQ
You can use bash arrays to store your values:
ruleId=($($whitelist | jq -r '.[].ruleId'))
alert=($($whitelist | jq -r '.[].alertName'))
...
and then iterate over them. Example:
for (( i = 0; i < "${#ruleId[@]}"; i++ )); do
id="${ruleId[i]}"
al="${alert[i]}"
...
echo "$(curl --data-urlencode "ruleId=$id" ...
done
This works if and only if the values returned by your commands are single words (no spaces in them) or they are properly quoted. If you have more complex values you cannot simply assign them to an array with array=($(command))
. You would get more cells than values in your array.
multi extract values with JQ
Using tr
like this is a bit hacky, but:
$ cat input
{
"range": "Sheet!A2:B100",
"majorDimension": "ROWS",
"values": [
[
"customer1_name",
"customer1@email.com",
"customer1_phone",
"customer1_city"
],
[
"customer2_name",
"customer2@email.com",
"customer2_phone",
"customer2_city"
]
]
}
$ jq -rc '.values[]' input | tr -d '["]' | while IFS=, read var1 var2 var3 var4; do echo "$var1 $var2 $var3 $var4"; done
customer1_name customer1@email.com customer1_phone customer1_city
customer2_name customer2@email.com customer2_phone customer2_city
You can also do:
$ jq -rc '.values[][]' input | while read name; read email; read phone; read city; do echo "$name $email $phone $city"; done;
customer1_name customer1@email.com customer1_phone customer1_city
customer2_name customer2@email.com customer2_phone customer2_city
Related Topics
Search Ip from a Text File in .Csv Log File, If Found Add New Column Next to It
Shell: What Is The Purpose of ${Var:-} When Var Is Unset or Null
How to Enable Spell Checker in Google Colab (Colab Operates on Linux Os)
How to Write Content to File on Linux Sftp Server Using Sshclient
Perl-Mechanize Runs into Limitations - Several Debugging Attempts Started
Why Proc Process Faster Than Others
Is The Program 'Yes' Used for Anything Significant
Understanding Linux Display Variable
Three Dots Directory Traversal with Mv
Problem in Restoring Floating Toolbar for Qmainwindow
How to Get The Process Id of Command Executed in Bash Script
Building Swift Sourcekit on Linux
How to Programmatically Know If I Am in a Vm
Gcc: Linked Libraries in /Usr/Local/Lib Are Not Found, But /Etc/Ld/So.Conf.D/Libc.Conf Lists It
Cannot Find Module 'Firebase-Admin' When Trying to Deploy Firebase Functions