I have this input json as example:
INPUT
{
"service1": {
"action1": [
"example1"
],
"action2": [
"example2",
"example3",
"example4"
]
},
"service2": {
"action3": [
"example5"
],
"action4": [
"example6",
"example7",
"example8"
]
}
}
I need to remove parents: action1, action2, action3, action4 and preserve their children as join, is there a way to do that in jq ?
DESIRED OUTPUT
{
"service1": [
"example1",
"example2",
"example3",
"example4"
],
"service2": [
"example5",
"example6",
"example7",
"example8"
]
}
jq '.[] |= add'
Will generate
{
"service1": [
"example1",
"example2",
"example3",
"example4"
],
"service2": [
"example5",
"example6",
"example7",
"example8"
]
}
As you can try in this only demo
For add, please take a look at jq's documentation.
Related
Given this data, which is two distinct objects, one having an array of keys and the other a dictionary of key value pairs:
{
"servers": [
{
"location": "server4",
"services": [
"srv07",
"srv06",
"srv01",
"srv04"
]
},
{
"location": "server2",
"services": [
"srv07",
"srv02",
"srv05",
"srv03"
]
}
],
"release": {
"id": "release1",
"services": [
{
"service": "srv01",
"URL": "/srv01_service/v1.20.0"
},
{
"service": "srv02",
"URL": "/srv02_service/v1.14.0"
},
{
"service": "srv03",
"URL": "/srv03_service/v1.15.0"
},
{
"service": "srv04",
"URL": "/srv04_service/v1.18.0"
},
{
"service": "srv05",
"URL": "/srv05_service/v1.14.0"
},
{
"service": "srv06",
"URL": "/srv06_serv/v1.13.0"
},
{
"service": "srv07",
"URL": "/srv07_service/v1.19.0"
}
]
}
}
I am trying to produce this, the first object with the keys replaced with the values from the dictionary. NOTE: I would be fine with renaming services[] to URLs[] if it makes things easier.
{
"servers": [
{
"location": "server4",
"services": [
"/srv07_service/v1.19.0",
"/srv06_serv/v1.13.0",
"/srv01_service/v1.20.0",
"/srv04_service/v1.18.0"
]
},
{
"location": "server2",
"services": [
"/srv07_service/v1.19.0",
"/srv02_service/v1.14.0",
"/srv05_service/v1.14.0",
"/srv03_service/v1.15.0"
]
}
]
}
My latest attempt is close but returns something akin to a Cartesian.
. | .servers[].services[] = (.servers[] as $s | .release.services[] | select(.service as $v | $s.services[] | index($v)).URL) | {servers}
Create an INDEX to lookup in, then map each element you want to change according to the index.
jq '
INDEX(.release.services[]; .service) as $index
| {servers} | .servers[].services[] |= $index[.].URL
'
{
"servers": [
{
"location": "server4",
"services": [
"/srv07_service/v1.19.0",
"/srv06_serv/v1.13.0",
"/srv01_service/v1.20.0",
"/srv04_service/v1.18.0"
]
},
{
"location": "server2",
"services": [
"/srv07_service/v1.19.0",
"/srv02_service/v1.14.0",
"/srv05_service/v1.14.0",
"/srv03_service/v1.15.0"
]
}
]
}
Demo
I have the following json input from a internet service:
{
"sunarme": "foo",
"id": "foo-id",
"name": "Foo bar",
"profile": [
{
"id": "test1",
"products": [
"product1",
"product2"
],
"description": "test1 description"
},
{
"id": "test2",
"products": [
"product3",
"product4",
"product5"
],
"description": "test2 description"
},
{
"id": "test3",
"products": [
"product6",
"product7",
"product8"
],
"description": "test2 description"
}
]
}
So I need to transform profile key from array to json object. This is the desired output:
{
"sunarme": "foo",
"id": "foo-id",
"name": "Foo bar",
"profile": {
"test1": [
"product1",
"product2"
],
"test2": [
"product3",
"product4",
"product5"
],
"test3": [
"product6",
"product7",
"product8"
]
}
}
I don't have any idea how to do it in jq command, please, could you help me?
Thanks in advance.
Use with_entries which lets you convert the array into an object if you adjust the .keys accordingly.
jq '.profile |= with_entries(.key = .value.id | .value |= .products)'
Demo
Or use reduce to build the object by iterating through the array.
jq '.profile |= reduce .[] as $p ({}; .[$p.id] = $p.products)'
Demo
Or use map to convert each array item into an object, then merge them using add.
jq '.profile |= (map({(.id): .products}) | add)'
Demo
Output is:
{
"sunarme": "foo",
"id": "foo-id",
"name": "Foo bar",
"profile": {
"test1": [
"product1",
"product2"
],
"test2": [
"product3",
"product4",
"product5"
],
"test3": [
"product6",
"product7",
"product8"
]
}
}
I have the following json output:
[
{
"serviceid": "service1",
"endpoints" : {
"endpoint1": [
"example1",
"example2",
"example3",
"example4"
],
"endpoint2": [
"example3",
"example4",
"example5",
"example6"
]
},
"version": "1.0"
},
{
"serviceid": "service2",
"endpoints" : {
"endpoint3": [
"example7",
"example8",
"example9",
"example10"
]
},
"version": "2.0"
}
]
So I need to remove endpoint1, endpoint2 and endpoint3 and preserve their children as array.
This is the desired output:
[
{
"serviceid": "service1",
"endpoints" : [
"example1",
"example2",
"example3",
"example4"
"example3",
"example4",
"example5",
"example6"
],
"version": "1.0"
},
"serviceid": "service2",
"endpoints" : [
"example7",
"example8",
"example9",
"example10"
],
"version": "2.0"
}
]
I don't have any idea to face it, please could you help me?
Thanks in advance.
Once you've fixed all the typos in your input (several commas and some curly braces were missing), this should work:
jq 'map(.endpoints |= [.[][]])'
Demo
I probably have some misconception, so need help with understanding what is exactly wrong.
At analytics.google.com I have two segments they differ by event label but both are from the same event. In analytics interface difference between segments is visible:
When I'm trying to get this same data with tool like query explorer results are also different:
However, when I'm getting this data with reporting API v4, all values are the same between segments. I have also tried it with API v3, which resulted in similar outcomes.
Here is my code:
googleapis.analyticsreporting('v4').reports.batchGet({
'headers': {'Content-Type': 'application/json'},
"auth": oauth2Client,
"resource":{
reportRequests:[
{
"viewId": "ga:"+Meteor.settings.admin.googleAPI.viewID,
"dateRanges":[{
"startDate": '2016-07-01',
"endDate": moment().format('YYYY-MM-DD'),
}],
"metrics": [{"expression":"ga:pageviews"},{"expression":"ga:avgtimeonpage"}],
"dimensions": [{"name":"ga:pagepath"},{"name":"ga:segment"}],
"segments": [{
"dynamicSegment":
{
"name": "version_bw",
"userSegment":
{
"segmentFilters": [
{
"simpleSegment":
{
"orFiltersForSegment": [
{
"segmentFilterClauses": [
{
"dimensionFilter":
{
"dimensionName": "ga:eventAction",
"operator": "EXACT",
"expressions": ["set-visual-code"]
}
},{
"dimensionFilter":
{
"dimensionName": "ga:eventLabel",
"operator": "EXACT",
"expressions": ["bw"]
}
}
]
}]
}
}]
}
}
},{
"dynamicSegment":
{
"name": "version_color",
"userSegment":
{
"segmentFilters": [
{
"simpleSegment":
{
"orFiltersForSegment": [
{
"segmentFilterClauses": [
{
"dimensionFilter":
{
"dimensionName": "ga:eventAction",
"operator": "EXACT",
"expressions": ["set-visual-code"]
}
},{
"dimensionFilter":
{
"dimensionName": "ga:eventLabel",
"operator": "EXACT",
"expressions": ["color"]
}
}
]
}]
}
}]
}
}
}]
}
]
}
}, function(err, response) {
if (err) {
console.log('API Error: '+ err);
return;
}
var rows = response.reports[0].data.rows;
for (var i = 0; i < rows.length; i++) {
console.log(rows[i].dimensions);
console.log(rows[i].metrics);
}
});
Which results in following output:
I20160719-14:09:10.405(2)? [ '/', 'version_bw' ]
I20160719-14:09:10.406(2)? [ { values: [ '373', '174.11977715877438' ] } ]
I20160719-14:09:10.406(2)? [ '/', 'version_color' ]
I20160719-14:09:10.407(2)? [ { values: [ '373', '174.11977715877438' ] } ]
I20160719-14:09:10.407(2)? [ '/portfolio', 'version_bw' ]
I20160719-14:09:10.407(2)? [ { values: [ '468', '126.2876404494382' ] } ]
I20160719-14:09:10.407(2)? [ '/portfolio', 'version_color' ]
I20160719-14:09:10.408(2)? [ { values: [ '468', '126.2876404494382' ] } ]
I20160719-14:09:10.408(2)? [ '/portfolio/', 'version_bw' ]
I20160719-14:09:10.409(2)? [ { values: [ '22', '229.54545454545453' ] } ]
I20160719-14:09:10.410(2)? [ '/portfolio/', 'version_color' ]
I20160719-14:09:10.410(2)? [ { values: [ '22', '229.54545454545453' ] } ]
I20160719-14:09:10.410(2)? [ '/portfolio/graphics', 'version_bw' ]
I20160719-14:09:10.410(2)? [ { values: [ '84', '60.073170731707314' ] } ]
I20160719-14:09:10.410(2)? [ '/portfolio/graphics', 'version_color' ]
I20160719-14:09:10.410(2)? [ { values: [ '84', '60.073170731707314' ] } ]
I20160719-14:09:10.411(2)? [ '/portfolio/graphics/some-graphic', 'version_bw' ]
I20160719-14:09:10.411(2)? [ { values: [ '134', '42.02290076335878' ] } ]
I20160719-14:09:10.411(2)? [ '/portfolio/graphics/some-graphic', 'version_color' ]
I20160719-14:09:10.411(2)? [ { values: [ '134', '42.02290076335878' ] } ]
I have to draw some lines by OpenLayers. The line features are coded as GeoJSON format. My code is ok for hard coded GeoJSON features. But, if I put this features in separate file and try to load it. It just does not work. I do not know what is the wrong with my loading external GeoJSON file. I have given both the code.
Code 1:
// This code is ok with hard coded GeoJSON features
map.addControl(new OpenLayers.Control.LayerSwitcher());
vectorLayer = new OpenLayers.Layer.Vector("Lines");
var myGeoJSON = { "type": "FeatureCollection",
"features":
[
{ "type": "Feature", "properties": { "LENGTH": 756.304000}, "geometry": { "type": "LineString", "coordinates": [ [ 18.105018, 59.231027 ], [ 18.104176, 59.230737 ], [ 18.103928, 59.230415 ], [ 18.103650, 59.230336 ], [ 18.103028, 59.230463 ], [ 18.102491, 59.230418 ], [ 18.101976, 59.230237 ], [ 18.100893, 59.230110 ], [ 18.100117, 59.230016 ], [ 18.097715, 59.230262 ], [ 18.096907, 59.230376 ], [ 18.096637, 59.230405 ], [ 18.096578, 59.230428 ], [ 18.096429, 59.230450 ], [ 18.096336, 59.230479 ], [ 18.096108, 59.230534 ], [ 18.095971, 59.230600 ], [ 18.095925, 59.230633 ], [ 18.095891, 59.230665 ], [ 18.094000, 59.231676 ], [ 18.093864, 59.231720 ] ] } }
,
{ "type": "Feature", "properties": { "LENGTH": 1462.390000}, "geometry": { "type": "LineString", "coordinates": [ [ 17.877073, 59.461653 ], [ 17.877116, 59.461598 ], [ 17.876936, 59.461507 ], [ 17.876936, 59.461323 ], [ 17.876773, 59.461098 ], [ 17.876430, 59.460885 ], [ 17.876413, 59.460553 ], [ 17.876576, 59.460280 ], [ 17.876575, 59.460078 ], [ 17.876762, 59.460060 ], [ 17.877371, 59.460042 ], [ 17.877808, 59.460046 ], [ 17.878641, 59.460046 ], [ 17.879010, 59.460078 ], [ 17.879337, 59.460044 ], [ 17.879526, 59.459878 ], [ 17.879749, 59.459563 ], [ 17.880058, 59.459538 ], [ 17.880435, 59.459503 ], [ 17.887550, 59.453608 ], [ 17.887696, 59.453430 ], [ 17.887971, 59.453150 ], [ 17.888221, 59.452843 ], [ 17.888246, 59.452721 ], [ 17.888435, 59.452609 ], [ 17.888470, 59.452568 ], [ 17.888517, 59.452410 ] ] } }
]
};
var geojson_format = new OpenLayers.Format.GeoJSON({
'internalProjection': map.baseLayer.projection,
'externalProjection': new OpenLayers.Projection("EPSG:4326")
});
map.addLayer(vectorLayer);
vectorLayer.addFeatures(geojson_format.read(myGeoJSON));
map.setCenter(
new OpenLayers.LonLat(18.068611, 59.329444).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 10
);
Code 2: This code shows an error that it could not load features
//This code does not work because it can not load the external GeoJSON file
map.addControl(new OpenLayers.Control.LayerSwitcher());
vectorLayer = new OpenLayers.Layer.Vector("Lines");
var myGeoJSON = new OpenLayers.Layer.Vector("Lines", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "ml/lines.json"
})
});
var geojson_format = new OpenLayers.Format.GeoJSON({
'internalProjection': map.baseLayer.projection,
'externalProjection': new OpenLayers.Projection("EPSG:4326")
});
map.addLayer(vectorLayer);
vectorLayer.addFeatures(geojson_format.read(myGeoJSON));
map.setCenter(
new OpenLayers.LonLat(18.068611, 59.329444).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 10
);
Thanks in advance
geojson_layer = new OpenLayers.Layer.Vector("GeoJSON", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "ml/lines.json",
format: new OpenLayers.Format.GeoJSON()
})
});
See my little example.