![如何解析非标准Json?](https://linux22.com/image/195940/%E5%A6%82%E4%BD%95%E8%A7%A3%E6%9E%90%E9%9D%9E%E6%A0%87%E5%87%86Json%EF%BC%9F.png)
我用来curl
检索数据。输出是 Json 输出,但它不是标准的。我尝试使用jq
但我得到空输出。例如:
我想从此输出中提取所有 ID 并将它们存储在数组中:
{"jsonrpc":"3","result":[{"hostid":"16729"},{"hostid":"16736"},{"hostid":"16731"},{"hostid":"16732"},{"hostid":"16733"},{"hostid":"16734"},{"hostid":"16735"},{"hostid":"16736"},{"hostid":"16738"},{"hostid":"16739"},{"hostid":"16746"},{"hostid":"16741"},{"hostid":"16742"},{"hostid":"16743"},{"hostid":"16744"},{"hostid":"16745"},{"hostid":"16746"},{"hostid":"16747"},{"hostid":"16748"},{"hostid":"16749"},{"hostid":"16756"},{"hostid":"16751"},{"hostid":"16752"},{"hostid":"16753"},{"hostid":"16754"},{"hostid":"16755"},{"hostid":"16756"},{"hostid":"16757"},{"hostid":"16758"},{"hostid":"16759"},{"hostid":"16766"},{"hostid":"16761"},{"hostid":"16762"},{"hostid":"16763"},{"hostid":"16764"},{"hostid":"16765"},{"hostid":"16766"},{"hostid":"16767"},{"hostid":"16768"},{"hostid":"16769"},{"hostid":"16776"},{"hostid":"16771"},{"hostid":"16772"},{"hostid":"16773"},{"hostid":"16774"},{"hostid":"16775"},{"hostid":"16776"},{"hostid":"16777"},{"hostid":"16778"},{"hostid":"16779"},{"hostid":"16786"},{"hostid":"16781"},{"hostid":"16782"},{"hostid":"16783"},{"hostid":"16784"},{"hostid":"16785"},{"hostid":"16786"},{"hostid":"16787"},{"hostid":"16788"},{"hostid":"16789"},{"hostid":"16796"},{"hostid":"16791"},{"hostid":"16792"},{"hostid":"16793"},{"hostid":"16794"},{"hostid":"16795"},{"hostid":"16796"},{"hostid":"16797"},{"hostid":"16798"},{"hostid":"16799"},{"hostid":"16866"},{"hostid":"16861"},{"hostid":"16862"},{"hostid":"16863"},{"hostid":"16864"},{"hostid":"16865"},{"hostid":"16866"},{"hostid":"16867"},{"hostid":"16868"},{"hostid":"16869"},{"hostid":"16816"},{"hostid":"16811"},{"hostid":"16812"},{"hostid":"16813"},{"hostid":"16814"},{"hostid":"16815"},{"hostid":"16816"},{"hostid":"16817"},{"hostid":"16818"},{"hostid":"16819"},{"hostid":"16826"},{"hostid":"16821"},{"hostid":"16825"},{"hostid":"16826"},{"hostid":"16827"},{"hostid":"16828"},{"hostid":"16829"},{"hostid":"16836"},{"hostid":"16831"},{"hostid":"11572"},{"hostid":"11573"},{"hostid":"11575"},{"hostid":"11576"},{"hostid":"11586"},{"hostid":"11629"},{"hostid":"11636"},{"hostid":"11632"},{"hostid":"11634"},{"hostid":"11736"},{"hostid":"11737"}],"id":1}
我期望这个输出:
( 16732 16733 ... 11737 )
即使使用 python 我也没有得到正确的输出。它不断返回 jsonrpc。例如:
我想从此输出中提取 ip 值
{"jsonrpc":"3","result":[{"interfaceid":"400","hostid":"16796","main":"3","type":"3","useip":"3","ip":"192.168.23.43","dns":"","port":"100","details":[]}],"id":1}
它只是一个长连接的字符串。有什么方法可以通过其他命令(如sed
或 )实现我想要的效果吗awk
?
答案1
您的 JSON 文档没有任何不标准的地方。两者都是完全有效且格式良好的 JSON 文档,您可以使用任何支持 JSON 的库或命令行工具来查询它们。对于此处的示例,我jq
在命令行上使用。
用于jq
将所有hostid
值存储在bash
数组中:
readarray -t hostid_values < <( jq -r '.result[].hostid' file.json )
这将从JSON 文档中的数组hostid
中提取所有值,并将它们读入.数组中任何预先存在的值都将被删除。result
hostid_values
bash
同样,将第二个 JSON 文档的值读取ip
到数组ip_values
中bash
:
readarray -t ip_values < <( jq -r '.result[].ip' file.json )
这两个 shell 代码都假设这些值不包含嵌入的换行符或 null。
将换行符嵌入值中后,您可能需要尝试类似的操作
unset -v hostid_values
eval "$( jq -r '@sh "hostid_values+=( \(.result[].hostid | tonumber) )"' file.json )"
这用于jq
创建数组的赋值语句hostid_values
。然后 shell 计算这些赋值语句。该tonumber
调用确保恶意文档无法通过发送命令数组而不是包含数字的字符串来将代码注入到我们的脚本中(如果发生这种情况,您将收到错误)。
对于ip
第二个文档中的值也是如此:
unset -v hostid_values
eval "$( jq -r '@sh "ip_values+=( \(.result[].ip | tostring) )"' file.json )"
答案2
要使用数据创建数组sed
,您可以尝试此命令
array=($(sed 's/{"hostid":"\([0-9]*\)"},/\1 /g;s/{.*\[//;s/{.*:"\(.*\)"}/\1/;s/\].*//' input_file))
要提取IP,你可以尝试这个sed
ip=$(sed 's/.*"ip":"\(.[^"]*\).*/\1/' iput_file)
输出
echo ${array[@]}
16729 16736 16731 16732 16733 16734 16735 16736 16738 16739 16746 16741 16742 16743 16744 16745 16746 16747 16748 16749 16756 16751 16752 16753 16754 16755 16756 16757 16758 16759 16766 16761 16762 16763 16764 16765 16766 16767 16768 16769 16776 16771 16772 16773 16774 16775 16776 16777 16778 16779 16786 16781 16782 16783 16784 16785 16786 16787 16788 16789 16796 16791 16792 16793 16794 16795 16796 16797 16798 16799 16866 16861 16862 16863 16864 16865 16866 16867 16868 16869 16816 16811 16812 16813 16814 16815 16816 16817 16818 16819 16826 16821 16825 16826 16827 16828 16829 16836 16831 11572 11573 11575 11576 11586 11629 11636 11632 11634 11736 11737
$ echo $ip
192.168.23.43