cat 2.txt | ./jq '{(.id): .custom}'
above command outputs
{
"1": {
"results": "Success"
}
}
{
"2": {
"input method": "touch",
"from": "Prescription Center",
}
}
{
"3": {
"entry point": "|All"
}
}
Expected output :
I want to print/save each object in a line.
cat 2.txt | ./jq '{(.id): .custom}'
{ "1": { "results": "Success" } }
{ "2": { "input method": "touch", "from": "Prescription Center" } }
{ "3": { "entry point": "|All" } }
will it be possible in shell script?
Per the jq manual
--compact-output / -c:
By default, jq pretty-prints JSON output. Using this option will result in more compact output by instead putting each JSON object on a single line.
Therefore the following should work:
cat 2.txt | ./jq -c '{(.id): .custom}'
Related
{
"data": {
"AWS_ACCESS_KEY_ID": "topsecret",
"AWS_SECRET_ACCESS_KEY": "s3cr3t"
},
"metadata": {
"created_time": "2022-09-16T06:49:11.45818Z",
"deletion_time": "",
"destroyed": false,
"version": 23
}
}
I've above data and I want my input as:
"data": {
"AWS_ACCESS_KEY_ID": "topsecret",
"AWS_SECRET_ACCESS_KEY": "s3cr3t"
}
jq query like this jq .data file.json is only giving me output like this:
{
"AWS_ACCESS_KEY_ID": "topsecret",
"AWS_SECRET_ACCESS_KEY": "s3cr3t"
}
Please help.
Are you sure you want invalid json? You can preserve the key if you enclose it in curly braces, e.g.:
jq '{ data }'
Output:
{
"data": {
"AWS_ACCESS_KEY_ID": "topsecret",
"AWS_SECRET_ACCESS_KEY": "s3cr3t"
}
}
Note that the above is a shorthand for { "data": .data }
I am working with jq and I am trying to add a new JSON object to a new key to an existing file.
I have the following JSON file, foobarbaz.json :
{
"example":{
"name": "stackOverflowQuestion"
}
}
I want to add a new entry under example, so to get the following output in foobar.json
{
"example": {
"name": "stackOverflowQuestion",
"new": {
"newfield": {
"key": "value"
}
}
}
}
I am using the following commands in the terminal:
$ tempvar='{"newfield":{"key":"value"}}'
$ cat foobarbaz.json | jq '.example.new=env.tempvar' > foobar.json
However, the output in foobar.json is somewhat unexpected:
{
"example": {
"name": "stackOverflowQuestion",
"new": "{\"newfield\":{\"key\":\"value\"}}"
}
}
Why does jq wrap the curly brackets with quotes, and why does it escape the double quotes?
Use fromjson to convert your string (the format all environment variables are in!) to the corresponding data structure, by decoding it as JSON content.
tempvar='{"newfield":{"key":"value"}}' jq '.example.new=(env.tempvar | fromjson)' <<'EOF'
{
"example":{
"name": "stackOverflowQuestion"
}
}
EOF
...emits as output:
{
"example": {
"name": "stackOverflowQuestion",
"new": {
"newfield": {
"key": "value"
}
}
}
}
Use the --argjson option to pass the pre-existing JSON snippet as a variable to the filter.
$ jq --argjson x "$tempvar" '.example.new=$x' foobarbaz.json
{
"example": {
"name": "stackOverflowQuestion",
"new": {
"newfield": {
"key": "value"
}
}
}
}
Note that tempvar isn't strictly necessary and can be dropped, if you are only defining it for use with the filter:
$ jq '.example.new={newfield: {key: "value"}}' foobarbaz.json
{
"example": {
"name": "stackOverflowQuestion",
"new": {
"newfield": {
"key": "value"
}
}
}
}
I'd like to know a quick way to insert a json to json.
$ cat source.json
{
"AWSEBDockerrunVersion": 2,
"containerDefinitions": [
{
"environment": [
{
"name": "SERVICE_MANIFEST",
"value": ""
},
{
"name": "SERVICE_PORT",
"value": "4321"
}
]
}
]
}
The SERVICE_MANIFEST is content of another json file
$ cat service_manifest.json
{
"connections": {
"port": "1234"
},
"name": "foo"
}
I try to make it with jq command
cat service_manifest.json |jq --arg SERVICE_MANIFEST - < source.json
But seems it doesn't work
Any ideas? The final result still should be a valid json file
{
"AWSEBDockerrunVersion": 2,
"containerDefinitions": [
{
"environment": [
{
"name": "SERVICE_MANIFEST",
"value": {
"connections": {
"port": "1234"
},
"name": "foo"
}
},
...
]
}
],
...
}
Updates.
Thanks, here is the command I run from your sample.
$ jq --slurpfile sm service_manifest.json '.containerDefinitions[].environment[] |= (select(.name=="SERVICE_MANIFEST").value=$sm)' source.json
But the result is an array, not list.
{
"AWSEBDockerrunVersion": 2,
"containerDefinitions": [
{
"environment": [
{
"name": "SERVICE_MANIFEST",
"value": [
{
"connections": {
"port": "1234"
},
"name": "foo"
}
]
},
{
"name": "SERVICE_PORT",
"value": "4321"
}
]
}
]
}
You can try this jq command:
jq --slurpfile sm SERVICE_MANIFEST '.containerDefinitions[].environment[] |= (select(.name=="SERVICE_MANIFEST").value=$sm[])' file
--slurpfile assigns the content of the file to the variable sm
The filter replaces the array .containerDefinitions[].environment[] with the content of the file only on the element having SERVICE_MANIFEST as name.
A simple solution would use --argfile and avoid select:
< source.json jq --argfile sm service_manifest.json '
.containerDefinitions[0].environment[0].value = $sm '
Or if you want only to update the object(s) with .name == "SERVICE_MANIFEST" you could use the filter:
.containerDefinitions[].environment
|= map(if .name == "SERVICE_MANIFEST"
then .value = $sm
else . end)
Variations
There is no need for any "--arg"-style parameter at all, as illustrated by the following:
jq -s '.[1] as $sm
| .[0] | .containerDefinitions[0].environment[0].value = $sm
' source.json service_manifest.json
I have a json file with city names in it and I would like to replace them with particular city codes from another file. The data.json is roughly:
{
"Customer": {
"CustomerName": "Customer1",
"City": "Cityname1"
}
}
{
"RelevantObject": false
}
{
"Customer": {
"CustomerName": "Customer2",
"City": "Cityname2"
}
}
# {...
The code list can be anything that is the easiest to feed to jq, I've been trying with codes.json:
{
"Cityname1": "Code1",
"Cityname2": "Code2"
}
but like I said, any format is fine. The hoped result:
{
"Customer": {
"CustomerName": "Customer1",
"City": "Code1"
}
}
{
"RelevantObject": false
}
{
"Customer": {
"CustomerName": "Customer2",
"City": "Code2"
}
}
I've been trying to read the file in with jq --argfile codes codes.json but I've had a hard time of referring to the $codes in the jq: .Customer.City=$codes.??
The key to a good answer here is:
.Customer.City |= $codes[.]
jq --argfile codes codes.json 'select(.Customer?)|{(.Customer.City):$codes[.Customer.City]}' data.json | jq -n '[inputs] | add'
Hi I have the below JSON file with nested object:
{
"Maps": {
"Campus": [
{
"name": "nus",
"Building": [
{
"name": "sde1",
"Floor": [
{
"name": "floor1"
},
{
"name": "floor2"
}
]
},
{
"name": "sde2"
}
]
},
{
"name": "ntu",
"Building": [
{
"name": "ece1",
"Floor": [
{
"name": "floor1"
},
{
"name": "floor2"
}
]
},
{
"name": "ece2"
}
]
}
]
}
}
I want to use jq to parse the above JSON file and get the below format:
nus>sde1>floor1
nus>sde1>floor2
ntu>ece1>floor1
ntu>ece1>floor2
basically I have to concatenate the Campus Name with Building Name and Floor name and put a < symbol in between.
If the nested object field Floor is not exist, ignore the parse and continue the next child object.
How to achieve that? thanks.
You can use the following jq command:
jq '.Maps.Campus[]|"\(.name)>\(.Building[]|"\(.name)>\(.Floor[]?.name)")"' file.json
jq is smart enough to print the combinations of .name and .Building[].name since .Building is an array. The same action get's applied to .Building[].name and Floor[]?.name. ? because floor is not always set.
Here is a solution which uses jq variables
.Maps.Campus[]
| .name as $campus
| .Building[]
| .name as $bldg
| .Floor[]?
| .name as $floor
| "\($campus)>\($bldg)>\($floor)"