shell 上的 JSON 解析

Ame*_*ina 12 zsh string json

如何在 shell 上解析 JSON 输出?

例如,Amazon Web Services 提供了一个 CLI 来检索您的实例的状态:

$ aws ec2 describe-instances <my_instance_id>
Run Code Online (Sandbox Code Playgroud)

但该命令返回一个 JSON 字符串。该命令的输出如下所示:

$ aws ec2 describe-instances x12345
{
    "Reservations" :
     {  
            "OwnerId": "1345345"
            "Groups": [], 
            "SecurityGroups": [
               {
                  "Foo" : "yes"
                  "Bar" : "no
               }
             ]
     }
}
Run Code Online (Sandbox Code Playgroud)

是否有可用于解析 JSON 输出的内置 shell?

例如,我想在 shell 变量中捕获FOO以下output["Reservations"]["SecurityGroups"][0]{"Foo"}.

如果有帮助,我对可以从 Zsh 工作的解决方案特别感兴趣。

phe*_*mer 12

这是对您的目标的回答,但不是您的问题。这意味着您可以在不使用 JSON 解析器的情况下实现目标。

AWS cli util 能够仅使用--query参数输出选择字段。这在此处记录

例如:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[0].GroupName' \
  --instance-id i-6b272337 \
  --output text
mongodb
Run Code Online (Sandbox Code Playgroud)

如果您愿意,您甚至可以选择多个字段:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[0].[GroupName,GroupId]' \
  --instance-id i-6b272337 \
  --output text
mongodb sg-710ffa14
Run Code Online (Sandbox Code Playgroud)

您还可以显示多个匹配的结构:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[*].[GroupName,GroupId]' \
  --instance-id i-6b272337 \
  --output text
mongodb sg-710ffa14
default sg-a0243bcc
Run Code Online (Sandbox Code Playgroud)


mik*_*erv 12

据我了解,您正在寻找“Foo”的价值。使用 shell 命令行工具可以容易地做到这一点jq。就像sed它实现了自己的解析器语言一样。鉴于你的例子:

json='
{
    "Reservations" :
     {  
            "OwnerId" : "1345345",
            "Groups" :  [],
            "SecurityGroups" : [
               {
                  "Foo" : "yes",
                  "Bar" : "no"
               }
             ]
     }
}'
Run Code Online (Sandbox Code Playgroud)

jq可以yes简单地得到:

printf %s "$json" |
jq '.[].SecurityGroups[0].Foo?'                                                
Run Code Online (Sandbox Code Playgroud)

输出

"yes"
Run Code Online (Sandbox Code Playgroud)

您可以使用.dot符号遍历对象哈希或字典列表,索引数组可以更简单地索引,正如您可能已经猜到的那样,数字、方括号索引。在上面的命令中,我使用空索引表单来指示我希望扩展该级别的所有可迭代项。用这种方式可能更容易理解:

printf %s "$json" | jq '.[][]'
Run Code Online (Sandbox Code Playgroud)

...它打破了哈希中第二级项目的所有值并让我......

"1345345"
[]
[
  {
    "Foo": "yes",
    "Bar": "no"
  }
]
Run Code Online (Sandbox Code Playgroud)

jq的功能而言,这几乎没有触及表面。它是一个非常强大的工具,用于在 shell 中序列化数据,它以经典的 Unix 风格编译为单个可执行二进制文件,很可能通过包管理器为您的发行版提供,并且它有很好的文档记录。请访问其git-page,看看自己。

顺便说一下,另一种处理分层数据的方法json- 至少是为了了解你正在使用的内容 - 可能是另一种方式并使用.dot符号来分解所有级别的所有值,例如:

printf %s "$json" | jq '..'

{
  "Reservations": {
    "OwnerId": "1345345",
    "Groups": [],
    "SecurityGroups": [
      {
        "Foo": "yes",
        "Bar": "no"
      }
    ]
  }
}
{
  "OwnerId": "1345345",
  "Groups": [],
  "SecurityGroups": [
    {
      "Foo": "yes",
      "Bar": "no"
    }
  ]
}
"1345345"
[]
[
  {
    "Foo": "yes",
    "Bar": "no"
  }
]
{
  "Foo": "yes",
  "Bar": "no"
}
"yes"
"no"
Run Code Online (Sandbox Code Playgroud)

但是,可能更好的是使用jq为各种类型的节点提供的众多发现或搜索方法中的一种。