jq - 在多个级别上应用过滤器

时间:2015-03-11 14:56:54

标签: json recursion jq flatten

我有一个像这样的json文件

{
    "log": {
            "version": {
                    "$t": "1.1"
            },
            "creator": {
                    "name": {
                            "$t": "Internet Explorer Network Inspector"
                    },
                    "version": {
                            "$t": "10.0.9200.17229"
                    }
            }
}

我需要压扁文件,以便它应该读取

{
    "log": {
            "version": "1.1",
            "creator": {
                    "name": "Internet Explorer Network Inspector",
                    "version": "10.0.9200.17229"
            }
}

我知道过滤器{"version": .version ."$t"}会将单个元素"version": {"$t": "10.0.9200.17229"}缩减为{"version": "10.0.9200.17229"},但此过滤器应递归应用于任何级别的任何元素。

3 个答案:

答案 0 :(得分:2)

您可以通过定义新函数来创建递归过滤器:

def untag: (objects | ."$t")
    // (objects | with_entries(.value |= untag))
    // (arrays | map(untag))
    // .
    ;
untag

所以给出这样的输入:

{
  "log": {
    "version": {
      "$t": "1.1"
    },
    "creator": {
      "name": {
        "$t": "Internet Explorer Network Inspector"
      },
      "version": {
        "$t": "10.0.9200.17229"
      }
    }
  }
}

你会回来的:

{
  "log": {
    "creator": {
      "name": "Internet Explorer Network Inspector",
      "version": "10.0.9200.17229"
    },
    "version": "1.1"
  }
}

答案 1 :(得分:0)

如果您的jq有walk,您可以按如下方式使用它,如果没有,您可以轻松谷歌其def并通过剪切和粘贴包含它:

walk( if type=="object" and has("$t")
      then .["$t"] else . end )

答案 2 :(得分:0)

扩展@JeffMercado的出色答案:

问题

您有一些生成JSON的命令,其中的字符串值表示为

{"some key": {"$t": "some string value"}}

,您希望将其转换为如下形式:

{"some key": "some string value"}

解决方案

将此内容放入您的~/.jq文件中:

def untag: (objects | ."$t")
  // (objects | with_entries(.value |= untag))
  // (arrays | map(untag))
  // .
  ;

像这样使用它:

some_command | jq untag

示例:

$ echo '{"some key": {"$t": "some string value"}}' | jq
{
  "some key": {
    "$t": "some string value"
  }
}

$ echo '{"some key": {"$t": "some string value"}}' | jq untag
{
  "some key": "some string value"
}