【问题标题】:How to improve performance on a slow jq script?如何提高慢 jq 脚本的性能?
【发布时间】:2017-09-10 05:42:14
【问题描述】:

我有一个 JSON 文档,如下所示:

{
    "SecurityGroups": [
        {
            "GroupName": "database",
            "GroupId": "sg-xxxxxx",
            "VpcId": "vpc-yyyyyyy",
            "IpPermissions": [
                {
                    "FromPort": 22,
                    "ToPort": 22,
                    "IpProtocol": "tcp",
                    "IpRanges": [
                        {
                            "CidrIp": "10.200.0.0/16"
                        },
                        {
                            "CidrIp": "10.200.30.79/32"
                        },
                        {
                            "CidrIp": "10.200.42.0/24"
                        }
                    ],
                    "UserIdGroupPairs": []
                },
                {
                    "FromPort": 5555,
                    "ToPort": 5555,
                    "IpProtocol": "tcp",
                    "IpRanges": [
                        {
                            "CidrIp": "10.200.0.0/16"
                        },
                        {
                            "CidrIp": "10.200.0.155/32"
                        }
                    ],
                    "UserIdGroupPairs": []
                },
                {
                    "FromPort": 4506,
                    "ToPort": 4506,
                    "IpProtocol": "tcp",
                    "IpRanges": [
                        {
                            "CidrIp": "10.200.0.0/16"
                        }
                    ],
                    "UserIdGroupPairs": []
                }
            ]
        }
    ]
}

我需要生成的输出如下:

sg-xxxxxx|database|22|22|tcp|10.200.0.0/16
sg-xxxxxx|database|22|22|tcp|10.200.30.79/32
sg-xxxxxx|database|22|22|tcp|10.200.42.0/24
sg-xxxxxx|database|5555|5555|tcp|10.200.0.0/16
sg-xxxxxx|database|5555|5555|tcp|10.200.0.155/32
sg-xxxxxx|database|4506|4506|tcp|10.200.0.0/16

我可以通过首先使用 jq 来生成 GroupId 的列表,然后循环遍历列表以将数据过滤到 jq 中来实现这一点。我是这样做的:

cat json.in | jq -r '.SecurityGroups[]|"\(.GroupId) \(.GroupName)"' | while read groupid groupname
do
        cat json.in | jq ".SecurityGroups[]|{GroupId,IpPermissions,IpPermissionsEgress}|select(.GroupId == \"$groupid\")" | jq -r '.IpPermissions[]|"\(.FromPort)|\(.ToPort)|\(.IpProtocol)|\(.IpRanges[].CidrIp)"' | sed "s/^/$groupid|$groupname|/"
done

我的解决方案很慢,我想改进它,任何指针?

【问题讨论】:

    标签: performance amazon-web-services parsing jq


    【解决方案1】:

    这是一种更有效的方法。使用-r 选项,以下过滤器

        .SecurityGroups[]
      | .GroupId as $gid
      | .GroupName as $gname
      | (.IpPermissions[], .IpPermissionsEgress[]?)
      | .FromPort as $from
      | .ToPort as $to
      | .IpProtocol as $pro
      | .IpRanges[]
      | "\($gid)|\($gname)|\($from)|\($to)|\($pro)|\(.CidrIp)"
    

    用样本数据产生

    sg-xxxxxx|database|22|22|tcp|10.200.0.0/16
    sg-xxxxxx|database|22|22|tcp|10.200.30.79/32
    sg-xxxxxx|database|22|22|tcp|10.200.42.0/24
    sg-xxxxxx|database|5555|5555|tcp|10.200.0.0/16
    sg-xxxxxx|database|5555|5555|tcp|10.200.0.155/32
    sg-xxxxxx|database|4506|4506|tcp|10.200.0.0/16
    

    请注意,这包括.IpPermissionsEgress[]?,因为尽管它在您的示例数据中不存在并且在您的脚本的第二部分中未使用,但它仍然存在于您的示例脚本的第一部分中,所以我认为您可能打算包含它。

    【讨论】:

    • 这可能是我最喜欢的新问题/答案对之一,因为它提供了一个很好的例子来说明jq 变量如何用作回溯前向引​​用:)
    猜你喜欢
    • 2020-06-05
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多