我正在尝试从我的Cyberpower UPS代理解析JSON(用于将数据导入InfluxDB / Grafana)。除了电池状态,我能够解析我想要的一切。如下所示,如果UPS与公用电源断开连接,状态为“放电”,但如果已连接,则该值包含逗号,“正常,完全充电” ....我无法找到解析数据的方法,因为知道该值可能有也可能没有逗号。如果值是“放电”,那么它工作正常,但由于“正常,完全充电”中的逗号,grep结果为“正常(显然缺少结束报价)。
单值的JSON:
"battery":{"state":"Discharging",
带逗号和空格的值的JSON:
"battery":{"state":"Normal, Fully Charged",
我的curl / greb。是否可以这样做来提取一个值,该值可能有也可能没有我想要的值的逗号?如果是这样,我做错了什么?
curl http://10.0.1.61:3052/agent/ppbe.js/init_status.js | grep -oP '(?<="battery":{"state":)[^,]*' | head -1
放电时的完整.js页面:
var ppbeJsObj = {
"status": {
"communicationAvaiable": true,
"onlyPhaseArch": false,
"utility": {
"state": "Blackout",
"stateWarning": true,
"voltage": "0",
"frequency": "60.00",
"voltages": null,
"currents": null,
"frequencies": null,
"powerFactors": null
},
"bypass": {
"state": "Normal",
"stateWarning": false,
"voltage": null,
"current": null,
"frequency": null,
"voltages": null,
"currents": null,
"frequencies": null,
"powerFactors": null
},
"output": {
"state": "Normal",
"stateWarning": false,
"voltage": "120.0",
"frequency": null,
"load": 58,
"watt": 522,
"current": null,
"outputLoadWarning": false,
"outlet1": null,
"outlet2": null,
"activePower": null,
"apparentPower": null,
"reactivePower": null,
"voltages": null,
"currents": null,
"frequencies": null,
"powerFactors": null,
"loads": null,
"activePowers": null,
"apparentPowers": null,
"reactivePowers": null,
"emergencyOff": null,
"batteryExhausted": null
},
"battery": {
"state": "Discharging",
"stateWarning": true,
"voltage": null,
"capacity": 99,
"runtimeFormat": 1,
"runtimeFormatWarning": false,
"runtimeHour": 0,
"runtimeMinute": 20,
"chargetimeFormat": null,
"chargetimeHour": null,
"chargetimeMinute": null,
"temperatureCelsius": null,
"highVoltage": null,
"lowVoltage": null,
"highCurrent": null,
"lowCurrent": null
},
"upsSystem": {
"state": "Normal",
"stateWarning": false,
"temperatureCelsius": null,
"temperatureFahrenheit": null,
"maintenanceBreak": null,
"systemFaultDueBypass": null,
"systemFaultDueBypassFan": null,
"originalHardwareFaultCode": "0x8080"
},
"modules": null,
"deviceId": 0
}
};
答案 0 :(得分:1)
你可以这样做:
curl http://10.0.1.61:3052/agent/ppbe.js/init_status.js | \
grep -oP '(?<="battery":\s*{)([^}]+)(?=})' | \
grep -oP '(?<="state": ")([^"]+)(?=")'
打破这个局面:
首先是正则表达式。
(?<=)
是群体背后的正面看法。因此(?<=aa)bb
将匹配bb
之前的任何aa
。
(?=)
是一个积极向前看的小组,因此,bb(?=aa)
将匹配bb
之后的所有aa
。
现在,命令,
获取文件:curl http://10.0.1.61:3052/agent/ppbe.js/init_status.js | \
找到battery
部分:grep -oP '(?<="battery":\s*{)([^}]+)(?=})' | \
这将把它转换成这种东西:
"state": "Normal, Fully Charged",
"stateWarning": true,
"voltage": null,
"capacity": 99,
"runtimeFormat": 1,
"runtimeFormatWarning": false,
"runtimeHour": 0,
"runtimeMinute": 20,
"chargetimeFormat": null,
"chargetimeHour": null,
"chargetimeMinute": null,
"temperatureCelsius": null,
"highVoltage": null,
"lowVoltage": null,
"highCurrent": null,
"lowCurrent": null
找到state
键/值:grep -oP '(?<="state": ")([^"]+)(?=")'
然后这个将返回值:
Normal, Fully Charged
对于更高级的JSON,您可以执行以下操作:
curl http://10.0.1.61:3052/agent/ppbe.js/init_status.js | \
grep -oP '(?<="battery":\s*{)(([^{}]++|(?1))*)(?=})' | \
grep -oP '(?<="state": ")([^"]+)(?=")'
请参阅(https://unix.stackexchange.com/a/147664)了解其工作原理。
你可以去掉变量声明和分号,然后像普通的JSON那样解析它。
// Here 'input' is your 'init_status.js' string
input = JSON.parse(input.replace(
/(?:^[\s\S]*?(?={))|(?:;[^;]*?$)/g,
""
))
如果您还需要“获取”该文件,那么您可以这样做:
const http = require('http');
http.get(
'http://10.0.1.61:3052/agent/ppbe.js/init_status.js',
response => {
let body = '';
// Read the data.
response.on('data', chunk => {body += chunk});
// The file is complete, now we can use it.
response.on('end', () => {
const data = JSON.parse(
body.replace(
/(?:^[\s\S]*?(?={))|(?:;[^;]*?$)/g,
""
)
);
// This logs the entire JSON object.
console.log(data);
// Getting the 'battery state'
console.log(data.status.battery.state);
});
}
);
答案 1 :(得分:1)
这应该有效:
grep -P -o '(?<="battery":{"state":")[a-zA-Z, ]+'
问候!
编辑:由OP评论编辑。
$ cat test.txt
var ppbeJsObj={"status":{"communicationAvaiable":true,
"onlyPhaseArch":false,
"utility":{"state":"Blackout",
"stateWarning":true,
"voltage":"0",
"frequency":"60.00",
"voltages":null,
"currents":null,
"frequencies":null,
"powerFactors":null},
"bypass":{"state":"Normal",
"stateWarning":false,
"voltage":null,
"current":null,
"frequency":null,
"voltages":null,
"currents":null,
"frequencies":null,
"powerFactors":null},
"output":{"state":"Normal",
"stateWarning":false,
"voltage":"120.0",
"frequency":null,
"load":58,
"watt":522,
"current":null,
"outputLoadWarning":false,
"outlet1":null,
"outlet2":null,
"activePower":null,
"apparentPower":null,
"reactivePower":null,
"voltages":null,
"currents":null,
"frequencies":null,
"powerFactors":null,
"loads":null,
"activePowers":null,
"apparentPowers":null,
"reactivePowers":null,
"emergencyOff":null,
"batteryExhausted":null},
"battery":{"state":"Discharging",
"stateWarning":true,
"voltage":null,
"capacity":99,
"runtimeFormat":1,
"runtimeFormatWarning":false,
"runtimeHour":0,
"runtimeMinute":20,
"chargetimeFormat":null,
"chargetimeHour":null,
"chargetimeMinute":null,
"temperatureCelsius":null,
"highVoltage":null,
"lowVoltage":null,
"highCurrent":null,
"lowCurrent":null},
"upsSystem":{"state":"Normal",
"stateWarning":false,
"temperatureCelsius":null,
"temperatureFahrenheit":null,
"maintenanceBreak":null,
"systemFaultDueBypass":null,
"systemFaultDueBypassFan":null,
"originalHardwareFaultCode":"0x8080"},
"modules":null,
"deviceId":0}};
$ grep -P -o '(?<="battery":{"state":")[a-zA-Z, ]+' test.txt
Discharging