Extracting lines from nested json file using Ubuntu - json

I have nested json file (each field can have one or more sons) with many lines. Something like this:
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
Using Ubuntu (or Unix) I would like to find the first 10 lines that their "batters" field is not empty (i.e. in the line one or more of its sons contain value (not null or "").

Related

JSON Parsing a Plain Text File

I have a lot of data I need to parse though.
I need to pull all pid's and price's.
`
[
{
"id": 159817,
"price": "10.69",
"stocked": true,
"store": {
"id": 809,
"nsn": "22036-0",
"pricingSource": "manual",
"lastUpdated": "2022-12-05T15:24:33.908Z"
},
"sharedFields": {
"type": "PRODUCT",
"id": 24549,
"pid": "12079",
"labels": [
{
"type": "default",
"value": "Chicken Sandwich",
"locale": "en"
},
{
"type": "fresh",
"value": "Chicken",
"locale": "en"
},
{
"type": "product_json",
"value": "Chicken",
"locale": "en"
}
],
"calMin": 600,
"calMax": 600,
"lastUpdated": "2021-12-31T13:49:22.794Z"
}
},
{
"id": 159818,
"price": "9.29",
"stocked": true,
"store": {
"id": 809,
"nsn": "22036-0",
"pricingSource": "manual",
"lastUpdated": "2022-12-05T15:24:33.908Z"
},
"sharedFields": {
"type": "PRODUCT",
"id": 25,
"pid": "1",
"labels": [
{
"type": "default",
"value": "Ham Sandwich",
"locale": "en"
},
{
"type": "fresh",
"value": "Ham",
"locale": "en"
}
],
"calMin": 540,
"calMax": 540,
"lastUpdated": "2021-07-09T19:30:00.326Z"
}
}
]
`
and I need to place them into a string like this, but on a scale of 150 products. I'd also need to change "pid" to "productId"
[{ "productId": "46238", "price": 6.09 }, { "productId": "40240", "price": 1.49 }]
I need to add a string before this data, but I'm pretty confident I can figure that part out.
I am pretty open to the easiest suggestion, whether that be VBS, Excel macro, etc.

Printing JSON like console.log prints it in Node.js

Wondering if it's possible to print JSON like Node.js prints it out. If there is some standard module or something to do that.
It has the spacing between keys, and when it's too long it goes onto a new line, etc. The coloring would be a bonus.
JSON.stringify(object, null, 2) pretty prints the JSON, wondering if there is something more hidden in there, or any standards, for doing it like Node.js does. Thank you.
This seems to be achievable by using util.inspect():
const util = require('util');
const testJson = `{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}`
x = JSON.parse(testJson);
x.x = x;
console.log(util.inspect(x, { colors: true }));
The options object takes a parameter called depth that determines how deep it will recurse. The default value is 2. If I increase it to 3:
console.log(util.inspect(x, { colors: true, depth: 3 }));
I get the following:
To make it recurse indefinitely pass depth: null. The default value seems to be 2 in the node cli as well.

How to flatten two json arrays using apache drill

{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
I have the above json and i want to flatten both batter and topping arrays.
so i tried doing:
SELECT flatten(topping) as toping,flatten(batters.batter) as bat FROM json.jsonfiles.`batter.json`;
which gives me
org.apache.drill.common.exceptions.UserRemoteException: VALIDATION
ERROR: From line 1, column 43 to line 1, column 49: Table 'batters'
not found SQL Query null [Error Id:
33cf80f2-f283-4401-90ce-c262474e0778 on acer:31010]
How can i solve this? Can we flatten two arrays in a single query?
You need to add table alias and refer it in columns. Below query works for me with sample data you have provided.
SELECT flatten(a.topping) as toping,flatten(a.batters.batter) as bat FROM dfs.tmp.`batter.json` a;

Angular2, Typescript,Json

I am going to use angular2 platform to develop an application. I am stuck at one point that "How do I print nested json in Angular2 Component's template".
json file:
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": "0000.55",
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
It's greatful if someone help me....:)
Try something like this:
<div *ngFor="let obj of jsonData">
<div>{{obj.id}}</div>
...
<div *ngFor="let bat of obj.batters.batter">
<div>{{bat.id}}</div>
<div>{{bat.type}}</div>
</div>
<div *ngFor="let topp of obj.topping">
<div>{{topp.id}}</div>
<div>{{topp.type}}</div>
</div>
</div>
You can change your object:
...,
"batters": [
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
],
...
then you can do like this:
<div *ngFor="let bat of obj.batters">
Hope this will help.

how to create a angular table row to have a collapsed row

I have a table which will have collapsed rows that have 2nd level info, but not all the rows will have this 2nd level data.
How can i write a controller to only show a 2nd level collapse row if the JSON script has a 2nd level?
With the following json defined in your controller:
$scope.cakes = [{ "id": "0001", "type": "donut", "name": "Cake",
"ppu": 0.55, "batters": "whatever",
"topping": [ { "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" } ] },
{ "id": "0002", "type": "cupcake", "name": "Cupcake",
"ppu": 0.60, "batters": "whatever",
"topping": [] },
{ "id": "0003", "type": "muffin", "name": "Muffin",
"ppu": 0.25, "batters": "whatever",
"topping": [] }
];
you can selectively show a second row in a table where cake.topping.length is greater than 0:
<table>
<tr ng-repeat-start="cake in cakes">
<td>{{cake.type}}</td><td>{{cake.name}}</td>
</tr>
<tr ng-repeat-end ng-show="cake.topping.length>0">
<td ng-repeat="t in cake.topping">{{t.type}}</td>
</tr>
</table>