jq 是一个很棒的工具。如果我有一个 json 文件,我可以提取键列表
像这样:
jq keys filename | tr -d '][",'
例如:
$jq keys pipeline/components/devsvr.json | tr -d '][",'
server1
server2
现在我想遍历每个键,只列出顶级字段名称(我正在尝试为一些 CloudFormation json 文件编写一个非常简单的验证器)。
shell 部分很简单 - 只是一个 for 循环,但我不知道如何对 jq 说:“只显示键 x 的所有字段名称。
然后,我将(在 shell 中)检查我需要的每个字段是否存在。顺便说一句,如果 json 格式错误,jq 将报告错误,这也很有用。
这是一个示例文件:
{
"server1": {
"type": "single-instance",
"stage": "10default",
"descriptor": {
"Resources": {
"Instance": {
"Properties": {
"InstanceType": "t2.medium",
"ImageId": {
}
}
},
"Metadata": {
"AWS::CloudFormation::Init": {
"app": {
"packages": {
"yum": {
"tmux": [],
"vim": []
}
},
"files": {
"sources": {},
"commands": {},
"services": {}
}
}
}
}
}
}
},
"server2": {
"type": "single-instance",
"stage": "10default",
"descriptor": {
"Resources": {
"Instance": {
"Properties": {
"InstanceType": "t2.medium",
"ImageId": {
}
}
},
"Metadata": {
"AWS::CloudFormation::Init": {
"app": {
"packages": {
"yum": {
"tmux": [],
"vim": []
}
},
"files": {
"sources": {},
"commands": {},
"services": {}
}
}
}
}
}
}
}
}
因此,对于上面的示例,我将运行 jq keys 来获取键列表,然后对其进行迭代。我可能已经用我评论过的 sed 示例回答了我自己的问题,但这有点像希思罗宾逊,IMO。结果如下:
$jq '.server1' /tmp/afile | sed -n 's#^ \"\([^"]*\).*$#\1#p'
type
stage
descriptor
(这将围绕 jq 'keys' 命令的输出循环)。
更新:根据@peak 和@Aaron,我可以这样做:
jq -r '. as $in | keys[] | . as $serverName | $in[$serverName] | keys | join(",") | "\($serverName) : \(.)"' pipeline/components/devsvr.json
devsvr : descriptor,stage,type
devsvr1 :
附带条件是http://json-schema.org的存在是为了更严格的实施。