【问题标题】:How to parse AWS CLI json output using jq to get array of volume-ids?如何使用 jq 解析 AWS CLI json 输出以获取卷 ID 数组?
【发布时间】:2014-10-17 02:52:57
【问题描述】:

我正在使用 AWS CLI 为这样的特定实例获取 BlockDeviceMappings 数组,

awscli 查询

aws ec2 describe-instances --filters "Name=tag:Name,Values=mongodb-*" "Name=private-ip-address,Values=$MEMBER_IP" \
    --output json --query "Reservations[*].Instances[*].BlockDeviceMappings[*]   

输出

[
    [
        [
            {
                "DeviceName": "/dev/xvda", 
                "Ebs": {
                    "Status": "attached", 
                    "DeleteOnTermination": true, 
                    "VolumeId": "vol-xvda-xxx", 
                    "AttachTime": "2014-10-13T14:40:13.000Z"
                }
            }, 
            {
                "DeviceName": "/dev/sdb", 
                "Ebs": {
                    "Status": "attached", 
                    "DeleteOnTermination": false, 
                    "VolumeId": "vol-sdb-xxxx", 
                    "AttachTime": "2014-10-13T14:40:13.000Z"
                }
            }, 
            {
                "DeviceName": "/dev/sdc", 
                "Ebs": {
                    "Status": "attached", 
                    "DeleteOnTermination": false, 
                    "VolumeId": "vol-sdc-xxx", 
                    "AttachTime": "2014-10-13T14:40:13.000Z"
                }
            }, 
            {
                "DeviceName": "/dev/sdd", 
                "Ebs": {
                    "Status": "attached", 
                    "DeleteOnTermination": false, 
                    "VolumeId": "vol-sdd-xxx", 
                    "AttachTime": "2014-10-13T14:40:13.000Z"
                }
            }
        ]
    ]
]

期望的输出

我想要一个分别为 /dev/sdb/dev/sdc/dev/sdd 的卷 ID 列表。

vol-sdb-xxxxx, vol-sdc-xxxx, vol-sdd-xxxxx

我尝试使用 jq 通过管道将 aws-cli 输出传送到 jq 进行解析,但我不断收到“jq: error: Cannot index array with string”。

另外,DeviceName 可能并不总是按照我可以假设数组中的第二、第三和第四个元素的顺序正确的顺序出现,所以我想确保如果可能,volume-ids 的期望输出始终采用以下形式:sdb、sdc、sdd。

更新 1

在尝试了 Jeff 的两个建议后:

建议 1

aws ec2 describe-instances --filters "Name=tag:Name,Values=mongodb-*" "Name=private-ip-address,Values=$MEMBER_IP" --output json --query "Reservations[*].Instances[*].BlockDeviceMappings[*]" | jq 'select(.DeviceName? | test("/dev/sd[bcd]")) | .Ebs.VolumeId'
error: test is not defined
select(.DeviceName? | test("/dev/sd[bcd]")) | .Ebs.VolumeId                      1 compile error

[Errno 32] Broken pipe

建议 2

aws ec2 describe-instances --filters "Name=tag:Name,Values=mongodb-*" "Name=private-ip-address,Values=$MEMBER_IP" --output json --query "Reservations[*].Instances[*].BlockDeviceMappings[*]" | jq 'select(  
         .DeviceName? as $dn
             | ["b","c","d"]
             | map($dn == "/dev/sd\(.)")
             | any
     )
   | .Ebs.VolumeId'

没有输出

我正在使用我认为是最新的 jq-1.4。

更新 2

以下适用于 jq-1.4,

aws ec2 describe-instances --filters "Name=tag:Name,Values=mongodb-*" "Name=private-ip-address,Values=$MEMBER_IP" --output json --query "Reservations[*].Instances[*].BlockDeviceMappings[*]" | jq '.. | select(.DeviceName? as $dn | ["b","c","d"] | map($dn == "/dev/sd\(.)") | any) | .Ebs.VolumeId'

【问题讨论】:

标签: json amazon-web-services aws-cli jq


【解决方案1】:

如果您使用的是实现了test 过滤器的最新版本,您可以这样做:

.. | select(.DeviceName? | test("/dev/sd[bcd]")) | .Ebs.VolumeId

否则,您将不得不进行一些调整:

.. | select(.DeviceName? == ("/dev/sdb","/dev/sdc","/dev/sdd")) | .Ebs.VolumeId

【讨论】:

  • 我正在使用jq-1.4,根据项目站点,这似乎是最新版本。我没有从你建议的任何一个版本中得到任何结果。有关我正在运行的命令和错误消息的详细信息,请参阅我更新的问题。
  • 前导.. | 是必需的。你在这两种情况下都忽略了它。您还应该省略过滤器中添加的空格,并将其全部放在一行中。我不知道它是否会像在命令行中那样工作。就像这里的可读性一样。没有要求你逐字逐句。
  • P.s.,正则表达式将在下一个版本中出现。当然不是1.4。不过 1.4.2 可能有,但最新版本肯定有。
  • 谢谢“丑陋”版本在我添加了`jq'后效果很好.. | ' 并删除了空格;) 将在 1.4.2 发布时使用更好的版本。
  • 我找到了一种更简洁的方法来编写该过滤器。逗号操作符非常方便。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多