command not found when executing jq for manipulating variable - linux

What I do:
RESPONSE_TEMPLATES=$(curl "https://maydomain.com/test)
I get back JSON which looks like this:
{
"templateId": "test",
"id": 1621030
}
{
"templateId": "test1",
"id": 5014
}
{
"templateId": "test3",
"id": 5015
}
echo $(${RESPONSE_TEMPLATES} | jq -r '.[]'| {templateId,id}')
Problem is that I always get error: [{"id":1386084,"templateId":"test: command not found
I do not know how I should write 3 steps so that it will display this as a string and not use after ""test: " as command.

With your shown samples please try following jq code. Using -r option to enable raw-mode option of jq then in main block using select function to check if component .templateId is test if yes then print its related id component value.
echo "${RESPONSE_TEMPLATES}" | jq -r 'select(.templateId=="test").id'

Related

Convert a json file to csv using shell script without using jq?

I want to convert a json file to csv using shell script without using jq. Is it possible?
Here is a json :
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
},
{
"id": "0002",
"type": "donut2",
"name": "Cake2",
"ppu": 0.5522,
}
I don't want to use jq.
I want to store it in a csv file.
Bare-bones core-only perl one-liner version, to complement the python and ruby ones already given:
perl -MJSON::PP -0777 -nE '$,=","; say #$_{"id","type","name","ppu"} for #{decode_json $_}' input.json
A more robust one would use a more efficient non-core JSON parser and a CSV module to do things like properly quote fields when needed, but since your sample data doesn't include such fields I didn't bother. Can if requested.
And the unrequested jq version, because that really is the best approach whether you want it or not:
jq -r '.[] | [.id, .type, .name, .ppu] | #csv' input.json
Bash is not the tool to do this at all. But if for some reason you cannot install jq, you can simply use Python 3, which comes by default in most distros of Linux and in MacOS.
#!/usr/local/bin/python3
import json
objs=json.loads("""
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55
},
{
"id": "0002",
"type": "donut2",
"name": "Cake2",
"ppu": 0.5522
}
]
""")
for item in objs :
print("{}{}{}{}{}{}{}".format(item['id'],",",item['type'],",",item['name'],",",item['ppu']))
If you do not have Python 3 either, you can then do it in Ruby, which also comes by default in most distros and MacOS :
#!/usr/bin/ruby
require 'json'
content = '
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55
},
{
"id": "0002",
"type": "donut2",
"name": "Cake2",
"ppu": 0.5522
}
]
'
JSON.parse(content).each { |item| puts "#{item['id']},#{item['type']},#{item['name']},#{item['ppu']}" }
You can then redirect the output to a file :
script.rb > output.csv
And thats it.
Nevertheless, if you can be completely sure of the format of your input, you can do some bash magic, specially using awk. But as others also said, please don't do that.

Is it possible with jq to use a deleted value in setting new ones?

I am using the bash to json parser jq
Considering the following command:
jq '. * .transitive | del(.transitive) | del(.scope,.scopedName)' package.json > package.github.json$$
And the following input:
{
"name": "navigation",
"transitive": {
"name": "navigation",
"scope": "bs",
"scopedName": "#bs/navigation"
}
}
I am trying to get the following output:
{
"name": "#bs/navigation"
}
Is there a way before doing the delete of .scopedName, to use it's value to set .name?
Transforming your input to your output is as simple as:
jq '{"name": .transitive.scopedName}'
...and of course you could just reorder things to set name before deleting transitive:
jq '.name=.transitive.scopedName | del(.transitive)'
That said, if you really want to use del() first, you can save content in a variable and use it later:
jq '
.transitive as $transitive |
del(.transitive) |
.name=$transitive.scopedName
'

Parse JSON Response to extract specific values Bash with out using any utility [duplicate]

This question already has answers here:
Parsing JSON with Unix tools
(45 answers)
Closed 4 years ago.
I tried using Parse JSON to array in a shell script
but unable to get required field. Below is my json:
{
"status": "UP",
"databaseHealthCheck":
{
"status": "UP",
"dataSource":
{
"maxActive": 100,
"maxIdle": 8,
"numActive": 0,
"url": "jdbc:oracle:thin:#hostname:port/db_name",
"userName": "test_123"
}
},
"JMSHealthCheck":
{
"status": "UP",
"producerTemplate":
{
"name": "Test_2",
"pendingCount": 0,
"operator": "<"
}
},
"diskSpace":
{
"status": "UP",
"total": 414302519296,
"free": 16099868672,
"threshold": 10485760
}
}
I want to extract pendingCount value under producerTemplate under JMSHealthCheck.
Have restriction to use utility like jq.
Bash Version 3.x
In absence of jq, you may use this gnu grep command:
read -r s < <(grep -zoP '"JMSHealthCheck":\s*{[^{}]*?"producerTemplate":\s*{[^{}]*?"pendingCount":\h*\K\d+' file.json)
echo "$s"
0
However, please keep in mind that parsing a JSON using regex is not recommended. If you have jq then it would be a very simple jq command lke this:
jq '.JMSHealthCheck.producerTemplate.pendingCount' file.json

Replacing date within a JSON config file

I'm new but trying to get a new script running but I need it to call on todays date as a variable within the configuration file so the program can be run.
I'm sure sure the best way to implement it so far this line will replace the correct part of the configuration file I need but I can't figure out how to get it to use the "todays date" e.g. date +%F command.
sed -i 's/"to_date":.*/"to_date":"date +%F"/' /config/settings
config following:
{
"username":"admin",
"password":"redhat",
"assumeyes":true,
"to_date": "2011-10-01",
"skip_depsolve":false,
"skip_errata_depsolve":false,
"security_only":false,
"use_update_date":false,
"no_errata_sync":false,
"dry_run":false,
"errata": ["RHSA-2014:0043", "RHBA-2014:0085"],
"blacklist": {
},
"removelist": {
},
"channels":[
{
"rhel-x86_64-server-5": {
"label": "my-rhel5-x86_64-clone",
"existing-parent-do-not-modify": true
},
"rhn-tools-rhel-x86_64-server-5": {
"label": "my-tools-5-x86_64-clone",
"name": "My Clone's Name",
"summary": "This is my channel's summary",
"description": "This is my channel's description"
}
},
{
"rhel-i386-server-5": "my-rhel5-i386-clone"
}
]
}
Using a proper JSON parser jq with the --arg field to pass the current date,
jq --arg inputDate $(date +%F) '.to_date = $inputDate' /config/settings
{
"username": "admin",
"password": "redhat",
"assumeyes": true,
"to_date": "2017-01-27",
"skip_depsolve": false,
"skip_errata_depsolve": false,
"security_only": false,
"use_update_date": false,
"no_errata_sync": false,
"dry_run": false,
"errata": [
"RHSA-2014:0043",
"RHBA-2014:0085"
],
"blacklist": {},
"removelist": {},
"channels": [
{
"rhel-x86_64-server-5": {
"label": "my-rhel5-x86_64-clone",
"existing-parent-do-not-modify": true
},
"rhn-tools-rhel-x86_64-server-5": {
"label": "my-tools-5-x86_64-clone",
"name": "My Clone's Name",
"summary": "This is my channel's summary",
"description": "This is my channel's description"
}
},
{
"rhel-i386-server-5": "my-rhel5-i386-clone"
}
]
}
The jq download and usage instructions are pretty straight forward. Recommend using it for manipulating JSON, instead of depending upon regex.
jq does not edit the file in-place, save it to a temporary file and rename it back, using GNU mktemp
jsonTemp=$(mktemp)
jq --arg inputDate $(date +%F) '.to_date = $inputDate' /config/settings > "$jsonTemp"
mv "$jsonTemp" /config/settings
To include the output of a command inside some quoted text, you have to use a subshell and use double-quotes so the text will get expanded :
sed -i "s/\"to_date\":.*/\"to_date\":\"$(date +%F)\"/" /config/settings
Also I second Inian's comment : you should be using jq to manipulate JSON data.
For example, the following command should do the modification you need :
jq ".toDate = $(date +%F)" /config/settings

search for first occurence of a string and print its value in linux

Hi i am using the below content in a file , i want the value of shortversion to be printed ,
{
"app_versions": [
{
"version": "15",
"shortversion": "0.0.15",
"title": "java expert",
"timestamp": 1469530069,
"appsize": 3436229,
"notes": ,
"mandatory": false,
"external": false,
"device_family": null,
"id": 9,
"app_id": 356250,
"minimum_os_version": "4.1",
,
{
"version": "7",
"shortversion": "0.0.7",
"title": "java expert",
"timestamp": 1469528889,
"appsize": 3436225,
,
{
"version": "3",
"shortversion": "0.0.3",
"title": "javaExpert",
"timestamp": 1469209202,
"appsize": 3420965,
how can i print the value of first occurrence of short version using sed,i have used the following awk command to get the shortversion awk -F'"' '/\"shortversion\"/{print $10;}' read.version this command is generating output of 0.0.15 which is correct , but the file is getting generated dynamically , need your valuable help on this
It is more modular to use a command line JSON parser like jq to parse your JSON input. It would be easier to maintain your script in case your JSON object tree change in the future.
You can get shortversion for the first element of your app_versions array with the following :
jq -r ". | .app_versions[1].shortversion" your_file.json
Maybe you can change a qualifier ':';eg
awk -F":" '/shortversion/{print $2}' datafile
and then use 'sed' to replace ','and '"';

Resources