I try to reformat the output of the sensors command:
sensors -j ftsteutates-i2c-0-73
{
"ftsteutates-i2c-0-73":{
"Adapter": "SMBus I801 adapter at efa0",
"VCC 3.3V":{
"in0_input": 3.331
},
"3.3V AUX":{
"in1_input": 3.359
},
"V_IN (12V)":{
"in2_input": 12.012
},
"VBAT 3.0V":{
"in3_input": 2.692
},
"CPU":{
"fan1_input": 660.000,
"fan1_alarm": 0.000,
"fan1_fault": 0.000
},
"Chassis":{
"fan3_input": 1200.000,
"fan3_alarm": 0.000,
"fan3_fault": 0.000
},
"CPU":{
"temp1_input": 51.000,
"temp1_alarm": 0.000,
"temp1_fault": 0.000
},
"Ambient":{
"temp2_input": 44.000,
"temp2_alarm": 0.000,
"temp2_fault": 0.000
},
"Core":{
"temp3_input": 54.000,
"temp3_alarm": 0.000,
"temp3_fault": 0.000
},
"Memory":{
"temp4_input": 42.000,
"temp4_alarm": 0.000,
"temp4_fault": 0.000
},
"PCH":{
"temp5_input": 54.000,
"temp5_alarm": 0.000,
"temp5_fault": 0.000
},
"Graphics":{
"temp6_input": 40.000,
"temp6_alarm": 0.000,
"temp6_fault": 0.000
}
}
}
What I am expecting is:
sensors -j ftsteutates-i2c-0-73 | jq '."ftsteutates-i2c-0-73" | del(."Adapter") | ???'
{
"VCC 3.3V": 3.331,
"3.3V AUX": 3.359,
"V_IN (12V)": 12.012,
"VBAT 3.0V": 2.692,
"CPU": 51.000,
"Chassis": 1200.000,
"Ambient": 44.000,
"Core": 54.000,
"Memory": 42.000,
"PCH": 54.000,
"Graphics": 40.000
}
But I cant figure out how to Map the values of the subkeys and also delete the *_alarm and *_fault subkeys or select just the first subkey which is always the *_input key.
EDIT:
I found, that the temp and fan values from CPU get joined, which need to be keeped.
Maybe it is possible to match the part of the subkey name in/fan/temp and join it together in the output name like:
sensors -j ftsteutates-i2c-0-73 | jq '."ftsteutates-i2c-0-73" | del(."Adapter") | ???'
{
"VCC 3.3V_in": 3.331,
"3.3V AUX_in": 3.359,
"V_IN (12V)_in": 12.012,
"VBAT 3.0V_in": 2.692,
"CPU_fan": 51.000,
"Chassis_fan": 1200.000,
"Ambient_temp": 44.000,
"Core_temp": 54.000,
"Memory_temp": 42.000,
"PCH_temp": 54.000,
"Graphics_temp": 40.000
}
Somehow like (dosnt work)
sensors -j ftsteutates-i2c-0-73 | jq '."ftsteutates-i2c-0-73" | del(."Adapter") | with_entries(.key |= gsub(" "; "_") | .value |= with_entries(select(.key | endswith("_input")) | .key |= gsub("_input"; "_in") | .key |= gsub("temp"; "_temp") | .key |= gsub("fan"; "_fan"))) | with_entries(.value |= if type == "object" then .[] else . end)'
or
sensors -j ftsteutates-i2c-0-73 | jq '."ftsteutates-i2c-0-73" | del(."Adapter") | with_entries(.value |= if type == "object" then with_entries(select(.key | endswith("_input")) | .key |= gsub("_input"; "_in") | .key |= gsub("temp"; "_temp") | .key |= gsub("fan"; "_fan")) else . end) | with_entries(.value |= if type == "object" then .[] else . end)'
3
Answers
I got the right answer:
This command does the following:
Iterates over each key-value pair, and if the value is an object, it selects the entries where the key ends with _input and then extracts the value.
This give me the desired output.
https://jqplay.org/s/KLkFpP0Q2yN3f9j
Here’s another way using the error suppression operator
?
(with jq 1.7+):Demo
For older versions, just add another types filter for
objects
(with jq 1.6+):Demo
Not recommended, but if the field ending with
_input
is always encoded as the first one, you could even shorten this with jq 1.7+ to:Demo
Result (due to its type, the
Adapter
field was deleted implicitly):You’d need to
--stream
the input at invocation in order to process broken-down parts individually, before they are collapsed in a superordinate structure Here’s one way:A simple solution using
jq
:How it works:
See it online.
h3. Remarks
_input
are present in an object, the value associated to the last one is returned;CPU
two times;depending on the JSON implementation, this can be reported as invalid
JSON or one of the keys is ignored (usually the last occurrence
overwrites any previous occurrences); this is also how
jq
works.