Reputation: 87
I have an application which writes/concatenates data into JSON, and then displays/graphs it via dygraphs. At times, various events can cause the values to go out of range. That range is user-subjective, so clamping that range at run-time is not the direction I am wishing to go.
I believe jq can help here - ideally I would be able to search for a field > x and if it is > x, replace it with x. I've gone searching for jq examples and not really found anything that's making sense to me yet.
I have spent a bit of time on this but not been able to make anything do what I think it should do ... at all. Like, I don't have bad code to show you because I've not made it do anything yet. I sincerely hope what I am asking is narrowed down enough for someone to be able to show me, in context, so I can extend it for the larger project.
Here's a line which I would expect to be able to modify:
{"cols":[{"type":"datetime","id":"Time","label":"Time"},{"type":"number","id":"Room1Temp","label":"Room One Temp"},{"type":"number","id":"Room1Set","label":"Room One Set"},{"type":"string","id":"Annot1","label":"Room One Note"},{"type":"number","id":"Room2Temp","label":"Room Two Temp"},{"type":"number","id":"Room2Set","label":"Room Two Set"},{"type":"string","id":"Annot2","label":"Room Two Note"},{"type":"number","id":"Room3Temp","label":"Room Three Temp"},{"type":"number","id":"State","label":"State"},{"type":"number","id":"Room4Temp","label":"Room Four Temp"},{"type":"number","id":"Quality","label":"Quality"}],"rows":[
{"c":[{"v":"Date(2019,6,4,20,31,13)"},{"v":68.01},{"v":68.0},null,{"v":62.02},{"v":55.89},null,null,{"v":4},{"v":69.0},{"v":1.052}]}]}
I'd want to do something like:
if JSONFile.Room2Set < 62
set Room2Set = 62
Here's a larger block of JSON which is the source of the chart shown below:
Upvotes: 0
Views: 1128
Reputation: 116780
With an invocation such as:
jq --arg col Room2Set --argjson mx 72 --argjson mn 62 -f clamp.jq input.json
where clamp.jq contains:
def clamp: if . > $mx then $mx elif . < $mn then $mn else . end;
(.cols | map(.id) | index($col)) as $ix
| .rows[].c[$ix].v |= clamp
the selected cells should be "clamped".
Upvotes: 1
Reputation: 134881
With a function clamp
functions defined like so (in your ~/.jq file or inline):
def clamp_min($minInc): if . < $minInc then $minInc else . end;
def clamp_max($maxInc): if . > $maxInc then $maxInc else . end;
def clamp($minInc; $maxInc): clamp_min($minInc) | clamp_max($maxInc);
And with that data, you'll want to find the corresponding cells for each row and modify the value.
$ jq --arg col "Room2Set" --argjson max '62' '
def clamp_max($maxInc): if . > $maxInc then $maxInc else . end;
(INDEX(.cols|to_entries[]|{id:.value.id,index:.key};.id)) as $cols
| .rows[].c[$cols[$col].index] |= (objects.v |= clamp_max($max))
' input.json
Upvotes: 2