Grep single value after match - json

I have a file containing:
{"id":1,"jsonrpc":"2.0","result":{"speed":0}}
How would I be able to grep "0" after "speed":"?
I have tried 'grep -o -P "speed":{1}', not what I am looking for.

You should use jq (sudo apt-get install jq on raspbian) for this task.
echo '{"id":1,"jsonrpc":"2.0","result":{"speed":0}}' | jq .result.speed
Result: 0
Since you said in your question that you have a file "containing" this line, you might want to use grep first to get only the line you're interested in, otherwise jq might throw an error.
Example file:
abc
{"id":1,"jsonrpc":"2.0","result":{"speed":0}}
123
Running grep "speed" yourfile.txt | jq .result.speed would output 0.

Related

Get Substring from Json Value using Grep

I have such json file:
{
"fruits": [
{
"name": "apple",
"type": "gala",
"product_id": "PA:app-1d39gsg",
"in_stock": "Y"
}
]
}
From this file, I want to get only this app-id39gsg using grep.
Tried
grep -o 'app-*' test.json
but doesn't work.
How do I get that substring from json data?
I would appreciate your advice.
I assume that your string always starts with PA:.
jq -r '.fruits[].product_id | sub("^PA:";"")' file.json
Output:
app-1d39gsg
Do you need to use only grep or can you use other common Linux tools as well?
Here's a suggestion using grep + sed:
grep -o 'app-\S*' text.json | sed 's/..$//'
Output:
app-1d39gsg
Explaining:
grep matches anything starting from "app-"
sed removes the last two characters
Note: This assumes you're using an implementation of grep which supports flag -o, like GNU grep does. You should be able to check your version with grep --version.

Parsing json output using jq -jr

I am running a puppet bolt command query certain information from a set of servers in json format. I am piping it to jq.. Below is what I get
$ bolt command run "cat /blah/blah" -n #hname.txt -u uid --no-host-key-check --format json |jq -jr '.items[]|[.node],[.result.stdout]'
[
"node-name"
][
"stdout data\n"
]
What do I need to do to make it appear like below
["nodename":"stdout data"]
If you really want output that is not valid JSON, you will have to construct the output string, which can easily be done using string interpolation, e.g.:
jq -r '.items[] | "[\"\(.node)\",\"\(.result.stdout)\"]"'
#peak thank you.. that helped. Below is how it looks like
$ bolt command run "cat /blah/blah" -n #hname.txt -u UID --no-host-key-check --format json |jq -r '.items[] | "[\"\(.node)\",\"\(.result.stdout)\"]"'
["node name","stdout data
"]
I used a work around to get the data I needed by using the #csv flag to the command itself. Sharing with you below what worked.
$ bolt command run "cat /blah/blah" -n #hname.txt -u uid --no-host-key-check --format json |jq -jr '.items[]|[.node],[.result.stdout]|#csv'
""node-name""stdout.data
"

How to parse echo json value?

I want to parse a value or convert a value into json format.
I have no idea how to do it.
echo -e $(kubectl get pods "test-pod" -o jsonpath="{range .status.containerStatuses[*]}{.state}"\\n"{end}")
map[running:map[startedAt:2019-06-07T00:51:34Z]]
map[running:map[startedAt:2019-06-07T00:51:40Z]]
map[running:map[startedAt:2019-06-07T00:51:44Z]]
map[waiting:map[message:Back-off 5m0s restarting failed container=con4 pod=test-pod_test(609c90e4-88be-11e9-ba5f-fa163e9a67be) reason:CrashLoopBackOff]]
I would like to get only all containers' status like [running, running, running, waiting].
Thanks in advance.
You can achieve it using the jq and keys[] command in jq. The following will be the command to use:
kubectl get pods kube-dns-86f4d74b45-khd4z -n kube-system -o json | jq -r '.status.containerStatuses[].state | keys[]'
The above command will give the following output of all container running or waiting or any state

How to pass bash variable value in json file

Add bash variables value to json file
I am trying to get latest zip file from nexus using below curl command.
Ouput of curl comes like this : 1.0.0.0-20190205.195251-396
In the json field i need this value(1.0.0.0-20190205.195251-396) to be updated like this: developer-service-1.0.0.0-20190205.195251-396.zip
ERROR: [2019-02-06T16:19:17-08:00] WARN: remote_file[/var/chef/cache/developer-service-.zip] cannot be downloaded from https://nexus.gnc.net/nexus/content/repositories/CO-Snapshots/com/GNC/platform/developer/developer-service/1.0.9.9-SNAPSHOT/developer-service-.zip: 404 "Not Found"
#!/bin/bash
latest=`curl -s http://nexus.gnc.net/nexus/content/repositories/CO-Snapshots/com/gnc/platform/developer/developer-service/1.0.9.9-SNAPSHOT/maven-metadata.xml | grep -i value | head -1 | cut -d ">" -f 2 | cut -d "<" -f 1`
echo $latest
sudo bash -c 'cat << EOF > /etc/chef/deploy_service.json
{
"portal" : {
"nexus_snapshot_version":"developer-service-${latest}.zip"
}
}
EOF'
The problem is that when you use "${latest}", it's inside single-quotes, and hence not treated as a variable reference, just some literal text; it's passed to a subshell (the bash -c, and that will parse it as a variable reference and replace it with the value of the variable latest, but that variable is only defined in the parent shell, not in the subshell. You could probably export the variable (so it gets inherited by subprocesses) and use sudo -E to prevent sudo from cleaning the environment (hence removing the variable)... But this whole thing is an overcomplicated mess; there's a much simpler way, using the standard sudo tee trick:
sudo tee ./deploy_service.json >/dev/null <<EOF
{
"portal" : {
"nexus_snapshot_version":"developer-service-${latest}.zip"
}
}
EOF
This way there's not single-quoted string, no subshell, etc. The variable reference is now just in a plain here-document (that's interpreted by the shell that knows $latest), and gets expanded normally.

Store Codeship build ID in variable using GREP

I am trying to use a grep to search a JSON output, I used a curl command to return the data from a particular codeship build and I want to use GREP to store said ID value in a variable. However after I run the command and try to echo out the value of the variable its blank.
Below are the commands:
export API_KEY=abc123
export PROJECT_ID=123456
export LAST_BUILD_ID=$(curl -s https://codeship.com/api/v1/projects/$PROJECT_ID.json?api_key=$API_KEY | grep -Eo '"builds":\[{"id":\d+' | grep -Eo --color=never '\d+' | tail -1)
export LAST_BUILD_URL=$(echo "https://codeship.com/api/v1/builds/$LAST_BUILD_ID/restart.json?api_key=$API_KEY")
My response : never use grep nor regex to parse json.
Instead, use a proper json parser.
In shell, take a look to jq.
Example, adapt it a bit :
#!/bin/bash
API_KEY=abc123
PROJECT_ID=123456
html=$(curl -s https://codeship.com/api/v1/projects/$PROJECT_ID.json?api_key=$API_KEY)
LAST_BUILD_ID=$(jq '.builds | .[] | .never' <<< "$html") # just guessing
LAST_BUILD_URL=$(echo "https://codeship.com/api/v1/builds/$LAST_BUILD_ID/restart.json?api_key=$API_KEY")
Note
If you provide the JSON, I will be able to be more specific with the jq command