This question already has answers here:
Parsing JSON with Unix tools
(45 answers)
Closed 4 years ago.
I have a variable in bash that is an output of Amazon EMR create command;
CLUSTER=$(aws emr create-cluster ...)
echo $CLUSTER
the output is like this:
{ "ClusterId": "j-9YWMBYN98LN7" }
What I need to do is to extract the value j-9YWMBYN98LN7 to a new variable, something like:
ID=$CLUSTER.(ClusterId)
Of course the above command doesn't work. I have tried with jq but no luck.
ID=$(jq -r '.ClusterId' $CLUSTER)
The thing is I'm not even sure what type $CLUSTER is. How do I extract the value j-9YWMBYN98LN7 there? Thanks
If you want to use jq, you can do it this way
ID=`echo ${CLUSTER} | jq -r '.ClusterId'`
If
echo $CLUSTER
gives you
{ "ClusterId": "j-9YWMBYN98LN7" }
then
ID=$(awk 'BEGIN{FS="\""}{print $4}' <<< "${CLUSTER}")
should do it.
echo "$ID"
j-9YWMBYN98LN7
Try the following:
ID=$(echo "${CLUSTER}" | sed 's/{ "ClusterId": "//' | sed 's/" }//')
That will isolate j-9YWMBYN98LN7, or whatever is between the last set of quotes, into the variable $ID.
I get the feeling there is more to what you need as you are probably planning on using the contents of $ID for something and there may be more efficient ways to capture that value for you. Maybe if you can explain a bit more how you plan on using the value we can provide even more actionable answers.
Related
This question already has answers here:
How do I assign the output of a command into an array?
(3 answers)
Closed 2 years ago.
I'm trying to get all results of jq query in a array in bash, but it gives me all results in the first array element.
Could you help me? I would like to having every result in one array element
bash-4.2$ try=$(tm run jobs:status::get -s "tm=serverA&work=*&status=Failed" | $PATH_API/jq -r '.statuses[].name // empty')
bash-4.2$ echo $try
job_B job_C
bash-4.2$ echo "${#try[#]}"
1
bash-4.2$
If the status names are sufficiently uncomplicated, you could add an extra pair of parentheses:
try=($(tm run ....))
(Consider also invoking jq without the -r option.)
Otherwise, you could consider using readarray, or other techniques for initializing bash arrays.
This question already has answers here:
Modify a key-value in a json using jq in-place
(8 answers)
Closed 1 year ago.
I have a daemon.json file which contains one line as below
{ "insecure-registries":["192.X.X.X:8123"] }
I am trying to use a variable to change generically to the current IP address. In bash script normally
I'd store in a variable like
myip=hostname -I | awk '{print $1}'
{ "insecure-registries":["$myip:8123"] }
How to use a kind of variable in JSON file?
If you have access to jq, I would recommend storing not JSON, but a jq filter, like
{"insecure-registries": ["\($ip):8123"]}
Assume the preceding is in file named foo.jq; then using jq as follows to produce JSON from the filter.
$ myip=$(hostname -I | awk '{print $1}') # 192.0.2.42, e.g.
$ jq -nf foo.jq --arg ip "$myip"
{
"insecure-registries": [
"192.0.2.42:8123"
]
}
JSON itself doesn't have a notion of substitution, and bash itself isn't really suitable for making substitutions like this.
This question already has answers here:
Parsing JSON with Unix tools
(45 answers)
Closed 6 years ago.
Below is my JSON string available in file, out of which I need to extract the value for status in shell script.
Expected Output: status=success
response.json
{"eventDate":null,"dateProccessed":null,"fileName":null,"status":"success"}
Please let me know, if you need any information
Look into jq. It is a very handy json parser.
If you want to extract just the status you can do something like:
jq -r '.status' response.json
# output
success
You can format your output as well to follow the results you want.
jq -r '"status=\(.status)"' response.json
# output
status=success
You can try sed:
sed -n 's|.*"status":"\([^"]*\)".*|status=\1|p' response.json
This question already has answers here:
Read JSON data in a shell script [duplicate]
(4 answers)
Closed 7 years ago.
Let's say that we have this kind of JSON file:
{
...
"quotes":{
"SOMETHING":10,
...
"SOMETHING_ELSE":120.4,
...
} }
How can I obtain those values and use them in order to add them together?
Am I able to do even this?
#!/bin/bash
#code ...
echo "$SOMETHING + $SOMETHING_ELSE" | bc
#code ...
#exit
I will obtain the JSON file with wget command. All I want is the content from this file.
Can you help me, please? I am a beginner in shell programming.
I usually use jq, a really fast json parser, to do this kind of things (because parsing a json file with tools like awk or sed is really error-prone).
Given an input file like this:
# file: input.json
{
"quotes":{
"SOMETHING":10,
"SOMETHING_ELSE":120.4
}
}
You can obtain the sum of the 2 fields with a simple filter:
jq '.quotes.SOMETHING + .quotes.SOMETHING_ELSE' input.json
# output -> 130.4
NOTE: jq is available in every major linux distribution. In a debian-derivative system you can install with a sudo apt-get install jq.
This will print out the sum of the selected lines' floats.
#!/bin/bash
awk '{ if ($1 ~ /"SOMETHING":/) {print}; if ($1 ~ /"SOMETHING_ELSE":/) {print} }' $1 | cut -d: -f2 | cut -d, -f1 | awk '{s+=$1};END{print s}'
This finds the lines you want, the plucks out the numbers, and adds them.
You should look up and learn jq as shown in Read the json data in shell script.
The tools in a "normal" shell installation like awk and sed all predate JSON by decades, and are a very very bad fit. jq is worth the time to learn.
Or use Python instead.
This question already has answers here:
filtering data using parameters
(2 answers)
Closed 7 years ago.
I am trying to parse json result from aws result, but I getting error or null when I am using $ip, when I am using specific IP it work. something wrong when I am using tne variable inside the jq command
#!/bin/bash
aws ec2 describe-addresses --region eu-west-1 > 1.txt
ipList=( "52.16.121.238" "52.17.250.188" )
for ip in "${ipList[#]}";
do
echo $ip
cat 1.txt | jq '.Addresses | .[] | select (.PublicIp==$ip) | .InstanceId'
#echo $result
done
Please advise.
You're using single quotes around your jq program, which is causing the shell variable to not be interpolated. Furthermore, even if it were, you would still need to add string quoting around the variable interpolation to make jq interpret it as a string literal. Since doing shell variable interpolation into jq programs is hard and error-prone, jq provides a command-line argument to this effect, --arg, intended to lift shell variables into jq variables. Your jq invocation would therefore look like this:
jq --arg ip "$ip" '.Addresses[] | select(.PublicIp == $ip) | .InstanceId'
Thanks for your help. the right format is:
cat 1.txt | jq ".Addresses | .[] | select(.PublicIp==\"$ip\") | .InstanceId"