Как преобразовать прерывистые строковые элементы в json в массивы, используя jq - PullRequest
1 голос
/ 08 мая 2019

У меня есть политика IAM с элементами Statement.Action, которые являются массивами и строками в зависимости от количества записей в них.

Например, есть такие, как

    {
        "Sid": "Name1",
        "Effect": "Allow",
        "Action": [
            "logs:GetLogEvents",
            "ecs:DeleteCluster",
            "logs:PutRetentionPolicy",
            "logs:PutLogEvents",
            "s3:GetReplicationConfiguration"
        ],
       "Resource": "arn:aws:cognito-idp:*:*:userpool/*",
        "Condition": {
            "ForAllValues:StringEquals": {
                "aws:ResourceTag/VendorType": "ABC"
            }
        }
    },

, а также элементы Statement.Action, такие как

    {
        "Sid": "Name2",
        "Effect": "Allow",
        "Action": "cognito-identity:DeleteIdentityPool",
        "Resource": "arn:aws:cognito-identity:*:*:identitypool/*",
        "Condition": {
            "ForAllValues:StringEquals": {
                "aws:ResourceTag/VendorType": "ABC"
            }
        }
    },

По сути, я хочу иметь возможность сортировать элементы поAction.

Однако, поскольку некоторые элементы Action являются строковыми, а не массивами при выполнении следующей команды

jq '.Statement[].Action|=(. // [] | sort)' file.json 

Я получаю сообщение об ошибке

jq: error (at file.json:277): string ("cognito-id...) cannot be sorted, as it is not an array

Это решеноесли все Statement []. Action элементы были в массивах, а некоторые не были строками.

Поэтому, если я изменю вышеприведенную запись с ошибкой в ​​json на следующую, это решит проблему.

    {
        "Sid": "Name2",
        "Effect": "Allow",
        "Action": [
            "cognito-identity:DeleteIdentityPool"
        ],
        "Resource": "arn:aws:cognito-identity:*:*:identitypool/*",
        "Condition": {
            "ForAllValues:StringEquals": {
                "aws:ResourceTag/VendorType": "ABC"
            }
        }
    },

Какую комбинацию команд jq можно использовать, чтобы иметь записи, где Statement [].Действие - это строка, а не массив, который нужно преобразовать в массив, подобный описанному выше, чтобы я мог затем выполнить сортировку по элементам внутри него.

Спасибо за вашу помощь

1 Ответ

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

Предположим, что объекты с ключами «Action» находятся в массиве.Затем вы можете отсортировать значения «Action», которые являются массивами, написав:

map( .Action |= (if type=="array" then sort else . end) )

Или если вы хотите убедиться, что .Action всегда имеет значение массива:

map( .Action |= (if type=="array" then sort else [.] end) )

.Заявление

Так что вы, вероятно, захотите написать что-то вроде:

jq '.Statement[].Action |= (if type == "array" then sort else . end)' file.json 
...