代码之家  ›  专栏  ›  技术社区  ›  Guss

在jq中,select是否可以是可选的(即,如果未找到任何内容,则不要过滤掉该元素)

  •  2
  • Guss  · 技术社区  · 6 年前

    我正在使用JQ过滤一个事物列表,然后针对每个找到的事物,通过从子键中提取值将其重新格式化为单个字符串。

    考虑下面的示例文档:

    {
      "items": [
        {
          "id": "A",
          "active": true,
          "tags": [
            { "name": "foo", "value": 1 }
          ]
        },
        {
          "id": "B",
          "active": true,
          "tags": [
            { "name": "foo", "value":1 },
            {"name": "bar", "value":2}
          ]
        },
        {
          "id": "C",
          "active": false,
          "tags": [
            { "name": "foo", "value":1 },
            { "name": "baz", "value":3 }
          ]
        }
      ]
    }
    

    foo bar

    最初我做过这样的事情:

    jq -r '
       .items[] | 
       select ( .active == true ) | 
       ( .id + " -> [" + 
         ( .tags[] | select( .name == "foo" ) | .value | tostring ) +
         ", " +
         ( .tags[] | select( .name == "bar" ) | .value | tostring ) +
         "]"
       )
    '
    

    酒吧 B ,项目的行 A 被过滤掉。

    1 回复  |  直到 6 年前
        1
  •  2
  •   peak    6 年前

    您可以使用 if ... then ... else ... end 或许 // ,但最好也解决一些其他问题,例如:

     .items[]
     | select ( .active == true ) 
     | .id + " -> ["
       + (.tags | map(select(.name == "foo") | .value) | join(";"))
       + ", "
       + (.tags | map(select(.name == "bar") | .value) | join(";"))
       + "]"
    

    tostring ,或使用字符串插值,例如。

       .items[]
       | select ( .active == true ) 
       | .id 
         + " -> [\(.tags | map(select(.name == "foo") | "\(.value)") | join(";") ), "
         +      "\(.tags | map(select(.name == "bar") | "\(.value)" ) | join(";"))"
         + "]"
    

    变体使用 first 和字符串插值

    .items[]
    | select ( .active == true )
    | (first(.tags[] | select(.name == "foo") | .value) // "")  as $v
    | (first(.tags[] | select(.name == "bar") | .value) // "")  as $w
    | "\(.id) -> [\($v), \($w)]"
    

    使用字符串插值可以避免使用