【问题标题】:Find nested JSON objects using jq使用 jq 查找嵌套的 JSON 对象
【发布时间】:2021-12-08 17:02:57
【问题描述】:

有没有办法使用 jq 在高度嵌套的 JSON 文件中查找特定对象的位置和值?

我永远不知道它们会出现在 JSON 结构中的什么位置,我也不知道父母的名字。我只知道我要搜索的对象的名称。

例如,我试图查找“FIND_ME”对象在以下 JSON 中的位置,这与整个 JSON 结构以及“FIND_ME”中包含的值有关。所以对于这个 JSON:

{
    "system": {
        "operating_system_1": {
            "FIND_ME": {
                "special_detail_1": "some_detail",
                "special_detail_2": "some_detail"
            },
            "feature_1": {
                "detail_1": "some_detail"
            },
            "feature_2": {
                "detail_2": "some_detail"
            }
        },
        "operating_system_2": {
            "feature_1": {
                "FIND_ME": {
                    "special_detail_3": "some_detail",
                    "special_detail_4": "some_detail"
                },
                "detail_3": "some_detail"
            },
            "feature_2": {
                "detail_4": "some_detail"
            }
        },
        "operating_system_3": {
            "feature_1": {
                "detail_5": "some_detail"
            },
            "feature_2": {
                "detail_6": "some_detail"
            }
        }
    }
}

理想情况下,我会得到以下输出:

{
    "system": {
        "operating_system_1": {
            "FIND_ME": {
                "special_detail_1": "some_detail",
                "special_detail_2": "some_detail"
            }
        },
        "operating_system_2": {
            "feature_1": {
                "FIND_ME": {
                    "special_detail_3": "some_detail",
                    "special_detail_4": "some_detail"
                }
            }
        }
    }
}

这样我可以检查大量文件以确保“FIND_ME”没有出现在不应该出现的地方,从而导致错误。 我从其他问题中尝试了以下内容:

cat json_file | jq '..|.FIND_ME? | select(. != null)'

它给出了“FIND_ME”的值,像这样

{
  "special_detail_1": "some_detail",
  "special_detail_2": "some_detail"
}
{
  "special_detail_3": "some_detail",
  "special_detail_4": "some_detail"
}

但它不显示父结构。

【问题讨论】:

    标签: json jq


    【解决方案1】:

    试试

    jq --arg query "FIND_ME" '
      reduce ((paths | select(.[-1] == $query)) as $p | [$p, getpath($p)])
        as $f ({}; setpath($f[0]; $f[1]))
    ' json_file
    
    {
      "system": {
        "operating_system_1": {
          "FIND_ME": {
            "special_detail_1": "some_detail",
            "special_detail_2": "some_detail"
          }
        },
        "operating_system_2": {
          "feature_1": {
            "FIND_ME": {
              "special_detail_3": "some_detail",
              "special_detail_4": "some_detail"
            }
          }
        }
      }
    }
    

    Demo

    【讨论】:

    • 附录:为了提高效率,尤其是在输入量很大的情况下,您可以通过将 paths 替换为 paths(objects) 来提前过滤对象。
    • 这行得通 - 非常感谢。
    猜你喜欢
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    相关资源
    最近更新 更多