无法使用jq-string("")将JSON文件解析为CSV,并且无法添加数组

时间:2018-03-20 09:01:03

标签: json bash csv jq

这是output.json:https://1drv.ms/u/s!AizscpxS0QM4hJo5SnYOHAcjng-jww

我在sts中遇到问题:AsumeRole.Principal.Service部分有多个服务时

Principal": {
                        "Service": [
                            "ssm.amazonaws.com", 
                            "ec2.amazonaws.com"
                        ]
                    }

在我的代码中,它是.Principal.Service字段。 如果只有一个服务,没有问题

 "InstanceProfileList": [
            {
                "InstanceProfileId": "AIPAJMMLWIVZ2IXTOC3RO", 
                "Roles": [
                    {
                        "AssumeRolePolicyDocument": {
                            "Version": "2012-10-17", 
                            "Statement": [
                                {
                                    "Action": "sts:AssumeRole", 
                                    "Effect": "Allow", 
                                    "Principal": {
                                        "AWS": "*"
                                    }
                                }
                            ]
                        }, 
                        "RoleId": "AROAJPHJ4EDQG3G5ZQZT2", 
                        "CreateDate": "2017-04-04T23:46:47Z", 
                        "RoleName": "dev-instance-role", 
                        "Path": "/", 
                        "Arn": "arn:aws:iam::279052847476:role/dev-instance-role"
                    }
                ], 
                "CreateDate": "2017-04-04T23:46:47Z", 
                "InstanceProfileName": "bastionServerInstanceProfile", 
                "Path": "/", 
                "Arn": "arn:aws:iam::279052847476:instance-profile/bastionServerInstanceProfile"
            }
        ], 
        "RoleName": "dev-instance-role", 
        "Path": "/", 
        "AttachedManagedPolicies": [
            {
                "PolicyName": "dev-instance-role-policy", 
                "PolicyArn": "arn:aws:iam::279052847476:policy/dev-instance-role-policy"
            }
        ], 
        "RolePolicyList": [], 
        "Arn": "arn:aws:iam::279052847476:role/dev-instance-role"
    }, 
    {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17", 
            "Statement": [
                {
                    "Action": "sts:AssumeRole", 
                    "Effect": "Allow", 
                    "Principal": {
                        "Service": [
                            "ssm.amazonaws.com", 
                            "ec2.amazonaws.com"
                        ]
                    }
                }
            ]
        }, 

如果只存在一个服务,则没有问题,但如果存在多个服务,则会收到错误string ("") and array (["ssm.amazonaws.com) cannot be added

如何在一行中获取Principal.Service的所有值。

我的代码:

jq -rc '.RoleDetailList 
  | map(select((.AssumeRolePolicyDocument.Statement | length > 0) and 
        (.AssumeRolePolicyDocument.Statement[].Principal.Service) or 
        (.AssumeRolePolicyDocument.Statement[].Principal.AWS) or 
        (.AssumeRolePolicyDocument.Statement[].Principal.Federated) or 
        (.AttachedManagedPolicies | length >0) or 
        (.RolePolicyList | length > 0)) )[] 
      | [.RoleName,
         ([.RolePolicyList[].PolicyName,
          ([.AttachedManagedPolicies[].PolicyName] | join("--"))] 
         | join(" ")),
       (.AssumeRolePolicyDocument.Statement[] 
        | .Principal.Federated + "" + .Principal.Service + ""+.Principal.AWS)] 
       | @csv' ./output.json

期望的输出:

"dev-instance-role","dev-instance-role-policy","ssm.amazonaws.com--ec2.amazonaws.com--*"

当前输出:

"dev-instance-role","dev-instance-role-policy","*"

2 个答案:

答案 0 :(得分:1)

.Principal.Service似乎是字符串或字符串数​​组,因此您需要处理这两种情况。因此,请考虑:

def to_s: if type == "string" then . else join("--") end;

您可能希望使其更通用,以使其更强大或出于其他原因。

您可能还想简化您的jq过滤器,使其更易于理解和维护,例如:通过使用jq变量。还要注意

.x.a + .x.b + x.c 

可以写成:

.x | (.a + .b + .c)

答案 1 :(得分:1)

考虑添加其他条件以检查a v T11552 TRUE T11559 TRUE T11566 TRUE T11567 FALSE T11569 TRUE T11594 TRUE T11604 TRUE T11625 TRUE T11633 TRUE T11634 TRUE .Principal.Service还是array的类型:

string

输出:

jq -rc '.RoleDetailList 
        | map(select((.AssumeRolePolicyDocument.Statement | length > 0) and 
        (.AssumeRolePolicyDocument.Statement[].Principal.Service) or 
        (.AssumeRolePolicyDocument.Statement[].Principal.AWS) or 
        (.AssumeRolePolicyDocument.Statement[].Principal.Federated) or 
        (.AttachedManagedPolicies | length >0) or 
        (.RolePolicyList | length > 0)) )[] 
        | [.RoleName,
           ([.RolePolicyList[].PolicyName,
           ([.AttachedManagedPolicies[].PolicyName] | join("--"))] 
        | join(" ")),
         (.AssumeRolePolicyDocument.Statement[] 
        | .Principal.Federated + "" 
          + (.Principal.Service | if type == "array" then join("--") else . end) 
          + "" + .Principal.AWS)] 
       | @csv' ./output.json