【问题标题】:How to convert a JSON object to key=value format in jq?如何在 jq 中将 JSON 对象转换为 key=value 格式?
【发布时间】:2014-10-12 05:37:54
【问题描述】:

在 jq 中,如何将 JSON 转换为带有key=value 的字符串?

发件人:

{
    "var": 1,
    "foo": "bar",
    "x": "test"
}

收件人:

var=1
foo=bar
x=test

【问题讨论】:

    标签: json bash jq


    【解决方案1】:

    你可以试试:

    jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json
    

    这是一个演示:

    $ cat test.json
    {
        "var": 1,
        "foo": "bar",
        "x": "test"
    }
    $ jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json
    foo=bar
    var=1
    x=test
    

    【讨论】:

    • 有什么办法可以递归地做到这一点?
    • 有一个递归函数......但我想你需要说出要递归的字段。您是否有要递归的固定字段,或者只是“任何作为对象的值”?
    • 没有特别的。我将尝试一种不同的递归方法。
    • 我发现这个问题希望将 json 对象转换为键/值对数组 -- to_entries 正是我所需要的。
    • @aioobe 有没有办法可以将键大写?我试过\(.key | tr a-z A-Z) 无济于事。
    【解决方案2】:

    有什么办法可以递归地做到这一点?

    这是一个可以做你想做的功能:

    # Denote the input of recursively_reduce(f) by $in.
    # Let f be a filter such that for any object o, (o|f) is an array.
    # If $in is an object, then return $in|f;
    # if $in is a scalar, then return [];
    # otherwise, collect the results of applying recursively_reduce(f)
    # to each item in $in.
    def recursively_reduce(f):
      if type == "object" then f
      elif type == "array" then map( recursively_reduce(f) ) | add
      else []
      end;
    

    示例:发出 key=value 对

    def kv: to_entries | map("\(.key)=\(.value)");
    
    
    [ {"a":1}, [[{"b":2, "c": 3}]] ] | recursively_reduce(kv)
    #=> ["a=1","b=2","c=3"]
    

    更新:在 jq 1.5 发布后,walk/1 被添加为 jq 定义的内置。它可以与上面定义的 kv 一起使用,例如如下:

     walk(if type == "object" then kv else . end) 
    

    使用上述输入,结果将是:

    [["a=1"],[[["b=2","c=3"]]]]

    要“展平”输出,可以使用 flatten/0。这是一个完整的例子:

    jq -cr 'def kv: to_entries | map("\(.key)=\(.value)");
            walk(if type == "object" then kv else . end) | flatten[]'
    

    输入:

    [ {"a":1}, [[{"b":2, "c": 3}]] ]
    

    输出:

    a=1
    b=2
    c=3
    

    【讨论】:

      【解决方案3】:

      顺便说一句,以@aioobe 的出色回答为基础。如果您需要键全部为大写,您可以使用ascii_upcase 通过修改他的示例来做到这一点:

      jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'
      

      示例

      我有一个与你类似的场景,但想在创建用于访问 AWS 的环境变量时将所有键都大写。

      $ okta-credential_process arn:aws:iam::1234567890123:role/myRole | \
           jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'
      EXPIRATION=2019-08-30T16:46:55.307014Z
      VERSION=1
      SESSIONTOKEN=ABcdEFghIJ....
      ACCESSKEYID=ABCDEFGHIJ.....
      SECRETACCESSKEY=AbCdEfGhI.....
      

      参考文献

      【讨论】:

        【解决方案4】:

        没有jq,我可以使用grepsed 导出json 中的每个项目,但这仅适用于我们有键/值对的简单情况

        for keyval in $(grep -E '": [^\{]' fileName.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
            echo "$keyval"
        done
        

        这是一个示例响应:

        ❯ for keyval in $(grep -E '": [^\{]' config.dev.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
            echo "$keyval"       
        done
        "env"="dev"
        "memory"=128
        "role"=""
        "region"="us-east-1"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-10
          • 1970-01-01
          • 2021-06-08
          • 2022-06-12
          • 2015-03-22
          • 2017-03-29
          • 2016-12-14
          • 2021-06-05
          相关资源
          最近更新 更多