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

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

  •  1
  • emaV  · 技术社区  · 9 年前

    我有一个这样的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 回复  |  直到 6 年前
        1
  •  2
  •   Jeff Mercado    9 年前

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

    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"
      }
    }
    
        2
  •  0
  •   peak    6 年前

    如果你的jq有 walk ,你可以按如下方式使用它,如果没有,你可以很容易地搜索它的def并通过剪切和粘贴将其包括在内:

    walk( if type=="object" and has("$t")
          then .["$t"] else . end )
    
        3
  •  0
  •   jwfearn    6 年前

    扩展@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"
    }