web-dev-qa-db-ja.com

describe-instancesの出力を並べ替えますか?

このトピックに関する前の質問を見ましたが、答えは単に「スクリプト言語にパイプでつなぐ!」というものでした。 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

そして、ランダムな順序で正しいデータを出力します。データの最後の列であるタグ名、別名Tags[?Key==`Name`]でソートしたいのですが、生の形式では次のようになります。

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

考え?

9
ColinK

簡潔な答え

追加

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

あなたの表現の終わりに。括弧(_[]_)は構造をフラット化し、sort_by(...)は結果(4列のテーブル)を4番目の列でソートします。完全なクエリは次のようになります。

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

長い答え

現在のクエリ結果を検査する

_describe-instances_ docs によると、_describe-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"
    ]
  ]
]
_

クエリ結果の平坦化

上記のクエリの結果から、テーブルのリスト(_[[{},{}],[{}]]_)を取得していることがわかります。代わりに、ネストされていない単一のテーブル(_[{},{},{}]_)が必要だと思います。これを実現するには、クエリの最後に_[]_を追加するだけです。

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

これにより構造が平坦化され、

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

次に、テーブルを並べ替えます。

テーブルの並べ替え

_sort_by_を使用する場合は、式の前に_&_(アンパサンド)を付けることを忘れないでください。このようにして、その式への参照を指定し、それを_sort_by_に渡します。

例:data | sort_by(@, &@)data | sort(@)と同等です。

作成するテーブルのTagName(_[LaunchTime,InstanceId,PrivateIpAddress,TagName]_)は4番目の列です。テーブルを式_[3]_にパイプして、その列を取得できます。

_TableExpression | [3]
_

しかし、代わりに、4番目の列でテーブルをsortしたいとします。あなたはこのようにすることができます:

_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"
  ]
]
_
15
myrdd

@ColinKの回答に対する拡張機能として、カスタムの列ヘッダーはあるが構文が苦手なテーブルを並べ替えたいと思いました。私は最終的にそれを動作させるようにしたので、誰かが同じことをしたい場合に備えて共有したいと思いました。 Stateの列を追加し、その列で並べ替えました。

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

これも機能する他の例です:

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