Получать значения только от связанных родителей при сопоставлении ребенка - PullRequest
0 голосов
/ 03 мая 2019

Я пытаюсь получить значение из массива путем сопоставления значения в дочернем массиве, но все, что я пытаюсь, либо ничего не возвращает, либо все члены родительского массива. Я хочу получить информацию только от родителей, у которых совпадает ребенок.

В частности, я хочу перечислить все группы безопасности AWS, в которых есть правила порта 22.

Это сокращенный пример вывода из командной строки aws, который я пытаюсь проанализировать:

{
    "SecurityGroups": [
        {
            "Description": "ssh and web group",
            "IpPermissions": [
                {
                    "FromPort": 22,
                    "ToPort": 22
                },
                {
                    "FromPort": 80,
                    "ToPort": 80
                }
            ],
            "GroupName": "ssh-web",
            "GroupId": "sg-11111111"
        },
        {
            "Description": "https group",
            "IpPermissions": [
                {
                    "FromPort": 443,
                    "ToPort": 443
                },
                {
                    "FromPort": 8443,
                    "ToPort": 8443
                }
            ],
            "GroupName": "https",
            "GroupId": "sg-22222222"
        }
    ]
}

Я пробовал это:

aws ec2 describe-security-groups |
    jq '.SecurityGroups[] as $top |
        .SecurityGroups[].IpPermissions[] |
        select(.FromPort == 22) |
        $top'

и это:

aws ec2 describe-security-groups |
    jq '. as $top |
        .SecurityGroups[].IpPermissions[] |
        select(.FromPort == 22) |
        $top'

Обе команды показывают обе записи массива верхнего уровня вместо одной, содержащей запись порта 22; они просто показывают весь вывод команды aws.

Человек, который ответил на этот вопрос ниже, конкретно ссылается на потенциальную проблему с областью видимости, которая у меня есть на самом деле, но его краткого описания того, как с ней бороться, мне недостаточно, чтобы понять:

jq - Как напечатать родительское значение объекта, когда я уже глубоко в дочерних объектах?

Я хочу увидеть это:

GroupName: "https"
GroupID: "sg-22222222"

Не думаю, что я полностью понимаю, как работает «как», что может быть моим камнем преткновения.

Ответы [ 2 ]

1 голос
/ 03 мая 2019

Не сходите с детьми, если вам нужен родитель.

.SecurityGroups[]
| select(any(.IpPermissions[]; .FromPort == 22))
| .GroupName, .GroupId

должно работать.

0 голосов
/ 03 мая 2019

вот решение, основанное на Unix-инструменте Walk-Path для JSON: jtc - там вы «кодируете» логику запроса прямо в путь:

bash $ <file.json jtc -x'[FromPort]:<22>d:[-3]' -y'[GroupId]' -y'[GroupName]' -l
"GroupId": "sg-11111111"
"GroupName": "ssh-web"
bash $ 

Объяснение: в команде есть два пути прохождения (это просто дано в -x, -y частях, где общая часть (-x) предшествует каждой уникальной части (-y),вместе они образуют каждый отдельный путь (эквивалент -w)):

  • [FromPort]:<22>d: [-3] находит каждую запись "FromPort": 22 и поднимается на 3 уровня (уровня) JSON вверх по дереву JSON, выбирая группу
  • [GroupId] и [GroupName] - выберите соответствующие значения (каждое в своей дорожке).

-l просто печатает метки для пройденных записей

если вы хотите найти любой порт эквалайзер22 (не просто FromPort) в IpPermissions, используйте вместо этого:

bash $ <file.json jtc -x'<IpPermissions>l:<22>d [-3]' -y'[GroupId]' -y'[GroupName]' -l
"GroupId": "sg-11111111"
"GroupName": "ssh-web"
bash $ 

PS> Раскрытие информации: я создатель инструмента jtc

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...