代码之家  ›  专栏  ›  技术社区  ›  Dimitri Kopriwa

JQ,根据情况如何计数?

  •  1
  • Dimitri Kopriwa  · 技术社区  · 6 年前

    使用jq,我需要根据两个标准在数组中获取计数:它必须 status === 'skipped' && ref.includes(version)

    [
      {
        "id": 15484,
        "sha": "52606c8da57984d1243f436e5d12e275db29a6e0",
        "ref": "v1.4.15",
        "status": "canceled"
      },
      {
        "id": 15483,
        "sha": "52606c8da57984d1243f436e5d12e275db29a6e0",
        "ref": "v1.4.15",
        "status": "canceled"
      },
      {
        "id": 15482,
        "sha": "1b4ccc1dc17e9b8ddb24550c5566d2be6b03465e",
        "ref": "dev",
        "status": "success"
      },
      {
        "id": 15481,
        "sha": "5b6ec939739c5a1513634f3b58bf96522917571d",
        "ref": "dev",
        "status": "failed"
      },
      {
        "id": 15480,
        "sha": "ec18d46f491a4645c68388df91fc41455b421e71",
        "ref": "dev",
        "status": "failed"
      },
      {
        "id": 15479,
        "sha": "dd83a6d6e58cc5114aed8016341ab3c5b3ebb702",
        "ref": "dev",
        "status": "failed"
      },
      {
        "id": 15478,
        "sha": "18ccaf4bc37bf65470b2c6ddaa69e5b4018354a7",
        "ref": "dev",
        "status": "success"
      },
      {
        "id": 15477,
        "sha": "f90900d733bce2be3d9ba9db25f8b51296bc6f3f",
        "ref": "dev",
        "status": "failed"
      },
      {
        "id": 15476,
        "sha": "3cf0431a161e6c9ca90e8248af7b4ec39c54bfb1",
        "ref": "dev",
        "status": "failed"
      },
      {
        "id": 15285,
        "sha": "d24b46edc75d8f7308dbef37d7b27625ef70c845",
        "ref": "dev",
        "status": "success"
      },
      {
        "id": 15265,
        "sha": "52606c8da57984d1243f436e5d12e275db29a6e0",
        "ref": "v1.4.15",
        "status": "success"
      },
      {
        "id": 15264,
        "sha": "9a15f8d4c950047f88c642abda506110b9b0bbd7",
        "ref": "v1.4.15-static",
        "status": "skipped"
      },
      {
        "id": 15263,
        "sha": "9a15f8d4c950047f88c642abda506110b9b0bbd7",
        "ref": "v1.4.15-static",
        "status": "skipped"
      },
      {
        "id": 15262,
        "sha": "76451d2401001c4c51b9800d3cdf62e4cdcc86ba",
        "ref": "v1.4.15-no-js",
        "status": "skipped"
      },
      {
        "id": 15261,
        "sha": "76451d2401001c4c51b9800d3cdf62e4cdcc86ba",
        "ref": "v1.4.15-no-js",
        "status": "skipped"
      },
      {
        "id": 15260,
        "sha": "515cd1b00062e9cbce05420036f5ecc7a898a4bd",
        "ref": "v1.4.15-cli",
        "status": "skipped"
      },
      {
        "id": 15259,
        "sha": "515cd1b00062e9cbce05420036f5ecc7a898a4bd",
        "ref": "v1.4.15-cli",
        "status": "skipped"
      },
      {
        "id": 15258,
        "sha": "b67acd3082da795f022fafc304d267d3afd6b736",
        "ref": "v1.4.15-node",
        "status": "skipped"
      },
      {
        "id": 15257,
        "sha": "b67acd3082da795f022fafc304d267d3afd6b736",
        "ref": "v1.4.15-node",
        "status": "skipped"
      },
      {
        "id": 15256,
        "sha": "4da4a788a85d82527ea568fed4f03da193842a80",
        "ref": "v1.4.15-bs-redux-saga-router-dom-intl",
        "status": "skipped"
      }
    ]
    

    我们还喜欢使用环境变量进行查询:

    • status=skipped
    • ref=v1.4.15

    此工作,但没有环境变量选项:

    cat test.json | jq '[.[] | select(.status=="skipped") | select(.ref | startswith("v1.4.15"))] | length'
    

    这怎么可能?

    答案:

    status=skipped; ref=v1.4.15; cat test.json | jq --arg REF "$ref" --arg STATUS "$status" -r '[.[] | select(.status==$STATUS) | select(.ref | startswith($REF))] | length'
    
    2 回复  |  直到 6 年前
        1
  •  0
  •   Dimitri Kopriwa    6 年前

    使用 length() 在将对象列表放入数组后,在筛选器末尾的函数

    jq '[.[] | select(.status == "skipped") | select(.ref | test("1.4.15"))] | length'
    

    但是仅仅返回对象就忽略了获取长度的逻辑

    jq '[.[] | select(.status == "skipped") | select(.ref | test("1.4.15"))]'
    

    test() 是用JSON字符串匹配regex的更强大的方法。这个 startswith() endswith() 如果字符串位于中间,则无法匹配这些字符串。

    使用变量,

    jq --arg status "$status" --arg ref "$ref" \
        '[.[] | select(.status == $status) | select(.ref | test($ref))]|length' json
    
        2
  •  2
  •   Dimitri Kopriwa    6 年前

    通过使用map(select(…)或等效工具,可以使用 length ,但通常更有效地使用通用计数函数,例如:

    def sigma(s): reduce s as $s (null; .+$s);
    
    sigma(.[] | select(.status=="skipped" and (.ref | startswith("v1.4.15") )) | 1)
    

    使用外壳和环境变量

    jq手册中介绍了使用shell和环境变量,但简而言之,传递字符串值的一种方法是使用命令行选项 --arg ,例如沿着以下线条:

    jq --arg status "$status" --arg ref "$ref" -f program.jq test.json