对描述实例的输出进行排序?

sort output of describe-instances?

我看到了关于这个主题的上一个问题,但答案只是"pipe it to a scripting language!",我觉得不满意。我知道 JMESPath 有 sort_bysort,但我不知道如何使用它们。

我有

aws ec2 describe-instances \
   --filters "Name=tag:Group,Values=production" "Name=instance-state-name,Values=running" "Name=tag:Name,Values=prod-*-${CURRENT_SHA}-*" \
   --query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value]' \
   --output table

它输出正确的数据,只是随机顺序。我想按数据的最后一列 Tag Name 排序,又名 Tags[?Key==`Name`],原始形式如下所示:

{
  "Tags": [{
    "Value": "application-server-ab3634b34364a-2",
    "Key": "Name"
  }, {
    "Value": "production",
    "Key": "Group"
  }]
}

想法?

简答

添加

[] | sort_by(@, &[3])

在你的表达的末尾。方括号 ([]) 会将结构展平,sort_by(...) 会将结果(四列 table)按第四列排序。完整的查询将是:

--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value][] | sort_by(@, &[3])'

长答案

正在检查您当前的查询结果

根据 describe-instances docsdescribe-instances 输出的结构如下所示:

{
  "Reservations": [
    {
      "Instances": [
        {
          "LaunchTime": "..LaunchTime..",
          "InstanceId": "R1I1",
          "PrivateIpAddress": "..PrivateIpAddress..",
          "Tags": [{"Key": "Name", "Value": "foo"}]
        },
        {
          "LaunchTime": "..LaunchTime..",
          "InstanceId": "R1I2",
          "PrivateIpAddress": "..PrivateIpAddress..",
          "Tags": [{"Key": "Name", "Value": "baz"}]
        }
      ]
    },
    {
      "Instances": [
        {
          "LaunchTime": "..LaunchTime..",
          "InstanceId": "R2I1",
          "PrivateIpAddress": "..PrivateIpAddress..",
          "Tags": [{"Key": "Name", "Value": "bar"}]
        }
      ]
    }
  ]
}

使用您的原始查询

--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value]'

会输出

[
  [
    [
      "..LaunchTime..",
      "R1I1",
      "..PrivateIpAddress..",
      "foo"
    ],
    [
      "..LaunchTime..",
      "R1I2",
      "..PrivateIpAddress..",
      "baz"
    ]
  ],
  [
    [
      "..LaunchTime..",
      "R2I1",
      "..PrivateIpAddress..",
      "bar"
    ]
  ]
]

扁平化查询结果

您可以在上面的查询结果中看到您正在获取 table 的列表 ([[{},{}],[{}]])。我想您反而想要一个非嵌套的 table ([{},{},{}])。为此,只需在查询末尾添加 [],即

--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value][]'

这将使结构变平,导致

[
  [
    "..LaunchTime..",
    "R1I1",
    "..PrivateIpAddress..",
    "foo"
  ],
  [
    "..LaunchTime..",
    "R1I2",
    "..PrivateIpAddress..",
    "baz"
  ],
  [
    "..LaunchTime..",
    "R2I1",
    "..PrivateIpAddress..",
    "bar"
  ]
]

现在是时候对 table 进行排序了。

排序 table

当使用 sort_by 时,您不应该忘记在表达式前添加 &(与符号)。通过这种方式,您可以为该表达式指定一个 reference,然后将其传递给 sort_by.

示例: data | sort_by(@, &@) 等同于 data | sort(@).

您创建的 table ([LaunchTime,InstanceId,PrivateIpAddress,TagName]) 中的 TagName 是第四列。您可以通过将 table 传递给表达式 [3]:

来获取该列
TableExpression | [3]

但是,您想要 排序 table 到第四列。您可以这样做:

TableExpression | sort_by(@, &[3])

结果查询将是:

--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`][] | [0].Value] | sort_by(@, &[3])'

查询结果:

[
  [
    "..LaunchTime..",
    "R2I1",
    "..PrivateIpAddress..",
    "bar"
  ],
  [
    "..LaunchTime..",
    "R1I2",
    "..PrivateIpAddress..",
    "baz"
  ],
  [
    "..LaunchTime..",
    "R1I1",
    "..PrivateIpAddress..",
    "foo"
  ]
]

答案是加| sort_by(@, &@[0][3])

aws ec2 describe-instances \
  --filters "Name=tag:Group,Values=production" "Name=instance-state-name,Values=running" "Name=tag:Name,Values=prod-*-${CURRENT_SHA}-*" \
  --query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value]| sort_by(@, &@[0][3])' \
  --output table

作为对@ColinK 答案的增强,我想对具有自定义列 headers 但在语法上遇到困难的 table 进行排序。我最终得到了它的工作所以我想我会分享以防其他人想要做同样的事情。我为州添加了一列并按该列排序。

--query 'sort_by(Reservations[*].Instances[*].{LaunchTime:LaunchTime, ID:InstanceId,IP:PrivateIpAddress,State:State.Name,Name:Tags[?Key==`Name`] | [0].Value}[], &State)' 

这是另一个同样有效的例子:

aws ec2 describe-instances --query 'Reservations[*].Instances[*].{Name:Tags[?Key==`Name`]|[0].Value,Instance:InstanceId} | sort_by(@, &[0].Name)'