0

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的存在是为了更严格的实施。

4

1 回答 1

1

... 使用尽可能小的工具集。

就处理 JSON 而言,您似乎只需要查看 jq 即可。

例如,您的第一个命令可以简化为:

jq -r 'keys[]' devsvr.json

keys_unsorted如果您希望密钥按原始顺序使用,请使用。

更重要的是,可以(并且可能应该)在 jq 中完成对键的迭代。我不确定您的确切要求是什么,但您应该能够轻松适应以下内容:

jq -r '.[] | keys_unsorted[]' devsvr.json

产生:

type
stage
descriptor
type
stage
descriptor

更新

根据对 Q 的更新,应考虑以下过滤器:

 keys[] as $serverName 
 | .[$serverName] 
 | "\($serverName) : \(keys|join(","))"
于 2018-12-04T16:04:38.323 回答