I am using jq parser to convert json to csv.
Input:
"abc":{
"a_val":true
},
"def":{
"b_val":false
},
"normaltext":{
"c_val":"text_value"
}
I am getting below output.
,,"text_value"
But my desire output is
"true", "false", "text_value"
or
true, false, text_value
Please help.
Thanks in advance.
If this doesn't work:
jq -r '[.abc.a_val, .def.b_val, .normaltext.c_val] | #csv' jsonfile
Then try this:
jq -r '[(.abc.a_val | tostring), (.def.b_val | tostring), .normaltext.c_val] | #csv' jsonfile
The input as shown is not quite valid JSON. The following assumes that surrounding braces have been added so as to produce valid JSON.
The following jq query produces the desired CSV:
[.abc.a_val, .def.b_val, .normaltext.c_val] | #csv
Typescript
$ jq -r '[.abc.a_val, .def.b_val, .normaltext.c_val] | #csv' input.json
true,false,"text_value"
Related
I am trying to curl some URL which returns a json file, as follows
[
10,
20,
30,
40,
]
now I am trying to save these value in file with a variable assigned to it.
need output in file as
a=10
b=20
c=30
d=40
thanks in advance.
You could use implode to create the letters by array index, which is provided in .key when to_entries is applied to an array.
jq -r 'to_entries[] | "\([.key + 97] | implode)=\(.value)"'
a=10
b=20
c=30
d=40
Demo
To provide individual names, you can introduce an array of names and use transpose to make the alignment:
jq -r '
[["Price", "Amount", "Value", "Tax"], .]
| transpose[] | "\(first)=\(last)"
'
Price=10
Amount=20
Value=30
Tax=40
Demo
Note: The list could also be provided from outside jq:
using a JSON array
jq -r --argjson names '["Price", "Amount", "Value", "Tax"]' \
'[$names, .] | transpose[] | "\(first)=\(last)"'
using positional parameters
jq -r '[$ARGS.positional, .] | transpose[] | "\(first)=\(last)"' \
--args Price Amount Value Tax
I am trying to get a value in second line of msg_values after colon:
{
"txt": {
"new": false,
"msg": "Generating 'value'\nGenerated new value: +somestring12345=\n",
"msg_values": [
"Generating 'value'",
"Generated new value: +somestring12345=",
""
]
}
}
jq -r '.[].msg_values[]' test.json returns:
Generating 'value'
Generated new value: +somestring12345=
What I want is just a:
+somestring12345=
I've tried with select and map but with no luck.
You could use index, e.g. along the lines of:
.txt|.msg_values[1]| index(":") as $ix | .[1+$ix:]
or more defensively:
.txt|.msg_values[1]| (index(":") // empty) as $ix | .[1+$ix:]
Since it’s not clear how exactly you want to trim the value, I’ll leave that detail to you.
Is using sed an option here?
jq -r '.[].msg_values[1]' test.json | sed -r "s/(.*):(.*)/\2/"
I have a json with a reasons array in the format [] or ["a","b","c"]. Basically i want to replace
drop_reasons=["a","b","c"] in json to drop_reasons="a,b,c" . I know we can use join(",") for this with jq .However , don't know how to modify it in the json .
I have tried this - cat test.json | jq ' .drop_reasons = .drop_reasons | join(",") ' | sponge test.json
, but doesn't see, to work , it tries to join the entire json rather than just drop_reasons. How do i tackle it ? Any help will be appreciated. Thanks
Sample json is :
{"id":11828997,"user":"8ddbceef-c374-44be-82f6-996b9d3f9cbd","timestamp":"2020-08-12T05:50:00+05:30","claim_timestamp":"2020-08-12T20:30:58+05:30","unique_key":"d56af2a7-10b8-4a98-b12c-a8aeab9fc56e","platform":"android","location_type":"indoor","activity_type":"unknown","activity_confidence":0,"total_day_steps":151744,"gf_total_steps":0,"step_count":122,"session_id":"1792b79c-1490-4b13-83e2-3c50ebce28f4","label":"indoor","is_claimed":false,"is_dropped":false,"drop_reasons":[],"is_valid":false,"invalid_reason":["steps>allowed_freq"],"conversion":null,"createdAt":"2020-08-12T20:30:58.385285+05:30","updatedAt":"2020-08-12T20:30:58.385285+05:30","location_uuid":null,"location_latitude":28.6673,"location_longitude":77.3915,"location_accuracy":1000,"location_speed":0,"location_timestamp":"2020-08-12T05:46:40+05:30","location_altitude":0,"location_ios_distance_filler":null,"location_ios_desired_accuracy":null,"location_distance_filter":0,"location_desired_accuracy":0,"location_course":0,"location_floor":null,"meta_data_geo_string":"28.6672867,77.3914746","meta_data_timezone":"Asia/Kolkata","meta_data_device_model":"Redmi Note 8 Pro","meta_data_device_brand":"redmi","meta_data_device_manufacturer":"xiaomi","meta_data_app_version":"0.9.31","meta_data_bundle_id":"com.pepkit.ssg","meta_data_build_no":"213","meta_data_plan_id":"a562ad72-54a9-4aea-941c-7f075e2a8b18"}
Using a pared-down sample JSON object with just the relevant key:
$ cat test.json
{
"drop_reasons": ["a","b","c"]
}
$ jq '.drop_reasons |= join(",")' test.json
{
"drop_reasons": "a,b,c"
}
Your sample with an empty array would change to an empty string.
x |= y is essentially shorthand for x = (x | y). The parens are what you were missing in your attempt; they're needed because of jq precedence rules.
I'm not familiar with jq, but if you just replace every "," with ,, it does the trick. It's a hack, so it could break if the input data changes format.
$ cat temp.txt
drop_reasons=["a","b","c"]
$ perl -pe 's/","/,/g' temp.txt
drop_reasons=["a,b,c"]
Struggling with formatting of data in jq. I have 2 issues.
Need to take the last array .rental_methods and concatenate them into 1 line, colon separated.
#csv doesn't seem to work with my query. I get the error string ("5343") cannot be csv-formatted, only array
jq command is this (without the | #csv)
jq --arg LOC "$LOC" '.last_updated as $lu | .data[]|.[]| $lu, .station_id, .name, .region_id, .address, .rental_methods[]'
JSON:
{
"last_updated": 1539122087,
"ttl": 60,
"data": {
"stations": [{
"station_id": "5343",
"name": "Lot",
"region_id": "461",
"address": "Austin",
"rental_methods": [
"KEY",
"APPLEPAY",
"ANDROIDPAY",
"TRANSITCARD",
"ACCOUNTNUMBER",
"PHONE"
]
}
]
}
}
I'd like the output to end up as:
1539122087,5343,Lot,461,Austin,KEY:APPLEPAY:ANDROIDPAY:TRANSITCARD:ACCOUNTNUMBER:PHONE:,
Using #csv:
jq -r '.last_updated as $lu
| .data[][]
| [$lu, .station_id, .name, .region_id, .address, (.rental_methods | join(":")) ]
| #csv'
What you were probably missing with #csv before was an array constructor around the list of things you wanted in the CSV record.
You could repair your jq filter as follows:
.last_updated as $lu
| .data[][]
| [$lu, .station_id, .name, .region_id, .address,
(.rental_methods | join(":"))]
| #csv
With your JSON, this would produce:
1539122087,"5343","Lot","461","Austin","KEY:APPLEPAY:ANDROIDPAY:TRANSITCARD:ACCOUNTNUMBER:PHONE"
... which is not quite what you've said you want. Changing the last line to:
map(tostring) | join(",")
results in:
1539122087,5343,Lot,461,Austin,KEY:APPLEPAY:ANDROIDPAY:TRANSITCARD:ACCOUNTNUMBER:PHONE
This is exactly what you've indicated you want except for the terminating punctuation, which you can easily add (e.g. by appending + "," to the program above) if so desired.
I have a json array that looks like this:
{
"StackSummaries": [
{
"CreationTime": "2016-06-01T22:22:49.890Z",
"StackName": "foo-control-eu-west-1",
"StackStatus": "UPDATE_COMPLETE",
"LastUpdatedTime": "2016-06-01T22:47:58.433Z"
},
{
"CreationTime": "2016-04-13T11:22:04.250Z",
"StackName": "foo-bar-testing",
"StackStatus": "UPDATE_COMPLETE",
"LastUpdatedTime": "2016-04-26T16:17:07.570Z"
},
{
"CreationTime": "2016-04-10T01:09:49.428Z",
"StackName": "foo-ldap-eu-west-1",
"StackStatus": "UPDATE_COMPLETE",
"LastUpdatedTime": "2016-04-17T13:44:04.758Z"
}
]
}
I am looking to create text output that looks like this:
foo-control-eu-west-1
foo-bar-testing
foo-ldap-eu-west-1
Is jq able to do this? Specifically, what would the jq command line be that would select each StackName in the array and output each key one per line?
jq --raw-output '.StackSummaries[].StackName'
$ jq -r '[.StackSummaries[] | .StackName] | unique[]' input.json
foo-bar-testing
foo-control-eu-west-1
foo-ldap-eu-west-1
The -r option strips the quotation marks from the output. You might not want the call to 'unique'.
For reference, if you wanted all the key names:
$ jq '[.StackSummaries[] | keys[]] | unique' input.json
[
"CreationTime",
"LastUpdatedTime",
"StackName",
"StackStatus"
]
Here is another solution
jq -M -r '..|.StackName?|values' input.json