繁体   English   中英

使用 Bash 和 jq 根据内部数组中的值过滤对象数组,加上匹配对象前后的 x 个对象?

[英]Use Bash and jq to filter array of objects based on values in an inner array, plus x objects before and after matching objects?

此问题类似,除了我试图在匹配对象之前和之后包含对象。

因此,例如,我想找到 type.name='pass' 的所有对象,以及在此 object 之前或之后的 X(比如 2)内的任何 object。

这个JSON:

    [
     {
       "class": "Something1",
       "type": {
         "name": "Foul"
       }
     },
     {
       "class": "Something2",
       "type": {
         "name": "Carry"
       }
     },
     {
       "class": "Something3",
       "type": {
         "name": "Pass"
       }
     },
     {
       "class": "Something4",
       "type": {
         "name": "Pass"
       }
     },
     {
       "class": "Something5",
       "type": {
         "name": "Carry"
       }
     },
     {
       "class": "Something6",
       "type": {
         "name": "Carry"
       }
     },
     {
       "class": "Something7",
       "type": {
         "name": "Other"
       }
     },
     {
       "class": "Something8",
       "type": {
         "name": "Other"
       }
     },
     {
       "class": "Something9",
       "type": {
         "name": "Carry"
       }
     },
     {
       "class": "Something10",
       "type": {
         "name": "Pass"
       }
     },
     {
       "class": "Something1",
       "type": {
         "name": "Carry"
       }
     },
     {
       "class": "Something2",
       "type": {
         "name": "Carry"
       }
     },
     {
       "class": "Something3",
       "type": {
         "name": "Carry"
       }
     },
     {
       "class": "Something4",
       "type": {
         "name": "Other"
       }
     },
     {
       "class": "Something5",
       "type": {
         "name": "Carry"
       }
     }
    ]

output 会是一个新的 JSON 字符串:

    [
      {
        "class": "Something1",
        "type": {
          "name": "Foul"
        }
      },
      {
        "class": "Something2",
        "type": {
          "name": "Carry"
        }
      },
      {
        "class": "Something3",
        "type": {
          "name": "Pass"
        }
      },
      {
        "class": "Something4",
        "type": {
          "name": "Pass"
        }
      },
      {
        "class": "Something5",
        "type": {
          "name": "Carry"
        }
      },
      {
        "class": "Something6",
        "type": {
          "name": "Carry"
        }
      },
      {
        "class": "Something8",
        "type": {
          "name": "Other"
        }
      },
      {
        "class": "Something9",
        "type": {
          "name": "Carry"
        }
      },
      {
        "class": "Something10",
        "type": {
          "name": "Pass"
        }
      },
      {
        "class": "Something1",
        "type": {
          "name": "Carry"
        }
      },
      {
        "class": "Something2",
        "type": {
          "name": "Carry"
        }
      }
    ]

或者它可以是 output 列表中上述对象的索引,然后可用于搜索原始 JSON。

由于上面引用的答案,我可以按“type.name”进行过滤,但我不知道如何包含周围的对象。

    $ passes=$(cat file.json | jq -c '[ .[] | select( .type.name | contains("Pass")) ]')

我正在处理的文件有 140,000 多行,所以效率很重要。

编辑:感谢@Gilles Quenot 修复了代码格式。

编辑:更正了 JSON 中的错误并解释了到目前为止所采用的方法。

让我们来看看 …

  1. 将输入修复为有效且格式正确的 JSON。
  2. 使用to_entries获取每个数组元素的索引。
  3. 使用map(select(…))模式提取与您的谓词匹配的所有键(即索引)。
  4. 使用相邻键“填充”您提取的键: + range(3) - 1
  5. 存储在变量中。
  6. 在条目上再次使用map(select(…))以提取索引与先前提取的索引之一匹配的任何项目

把它们放在一起:

to_entries
| map(select(.value.type.name=="Pass").key + range(3) - 1) as $keys
| map(select(.key|IN($keys[])).value)

range(3)-1产生-1,0,1这意味着将检查范围 1 内的所有索引。 要检查最大距离为 2 的所有索引,请使用range(5)-2

Output:

[
  {
    "class": "Something2",
    "type": {
      "name": "Carry"
    }
  },
  {
    "class": "Something3",
    "type": {
      "name": "Pass"
    }
  },
  {
    "class": "Something4",
    "type": {
      "name": "Pass"
    }
  },
  {
    "class": "Something5",
    "type": {
      "name": "Carry"
    }
  },
  {
    "class": "Something9",
    "type": {
      "name": "Carry"
    }
  },
  {
    "class": "Something10",
    "type": {
      "name": "Pass"
    }
  },
  {
    "class": "Something1",
    "type": {
      "name": "Carry"
    }
  }
]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM