【问题标题】:Using jq to parse and display multiple fields in a json serially使用jq串行解析并显示json中的多个字段
【发布时间】:2015-03-25 17:38:58
【问题描述】:

我有这个 Json

{
    "users": [
        {
            "first": "Stevie",
            "last": "Wonder"
        },
        {
            "first": "Michael",
            "last": "Jackson"
        }
    ]
}

使用 jq 我想连续显示名字和姓氏。像这样-

Stevie Wonder
Michael Jackson

这是我已经走了多远 -

jq '.users[].first, .users[].last'

但它显示

"Stevie"
"Michael"
"Wonder"
"Jackson"

注意以下几点:

  1. 我不想要的双引号。
  2. 我不要的回车。
  3. 混乱了。我的查询首先显示所有名字,然后显示所有姓氏。但是,我想要倒数第一对。

【问题讨论】:

    标签: json jq


    【解决方案1】:

    我推荐使用字符串插值:

    jq '.users[] | "\(.first) \(.last)"'
    

    reference

    【讨论】:

    • 如果你的数据是数字会好很多
    • 语法解释将使这个答案更有用。
    • 一个好的答案不应该只是在链接中进行解释。链接的网站可能发生任何事情,然后人们就会复制他们不理解的代码。
    • 如果您不希望输出用引号括起来,请添加 -r 开关。
    • jq '.[] | "id=\(.id) name=\(.name)"')附加名称或ID
    【解决方案2】:

    您可以使用addition 连接字符串。

    字符串是通过加入更大的字符串来添加的。

    jq '.users[] | .first + " " + .last'
    

    firstlast 都是字符串时,上述方法有效。如果您要提取不同的数据类型(数字和字符串),那么我们需要转换为等效类型。参考solution on this question。例如。

    jq '.users[] | .first + " " + (.number|tostring)'
    

    【讨论】:

    • 要消除 JSON 引号,请使用 -r 选项调用 jq,例如jq -r '.users[] | .first + " " + .last'
    • +1,但对于我的用例,我试图将两个数字格式化到同一行。此方法失败,因为它无法将" " 添加到数字中。 Eric 的回答为这种情况提供了更好的结果。
    • @Synesso:(.numA|tostring) + " " + (.numB|tostring) 应该可以工作。或者改用字符串插值:"\(.numA) \(.numB)".
    • 当我执行jq '.users[] | .first + " " + .last' 时,它运行得非常好,但导致.first.last 的值之间出现换行符。我将" " 更改为"@",然后在输出上执行sed 's/@/ /g' 以获得“John Smith”作为输出。像这样的东西:jq '.users[] | .first + "@" + .last' | sed 's/@/ /g'
    【解决方案3】:
    jq '.users[]|.first,.last' | paste - -
    

    【讨论】:

      【解决方案4】:

      我的方法是(您的 json 示例格式不正确.. 猜这只是一个示例)

      jq '.Front[] | [.Name,.Out,.In,.Groups] | join("|")'  front.json  > output.txt
      

      返回类似的东西

      "new.domain.com-80|8.8.8.8|192.168.2.2:80|192.168.3.29:80 192.168.3.30:80"
      "new.domain.com -443|8.8.8.8|192.168.2.2:443|192.168.3.29:443 192.168.3.30:443"
      

      并使用正则表达式 grep 输出。

      【讨论】:

        【解决方案5】:

        除了其他人的建议之外,我认为有两个选项值得一提。

        打印为 CSV/TSV

        $ cat file.json | jq -r '.users[] | [.first, .last] | @tsv'
        Stevie  Wonder
        Michael Jackson
        
        cat file.json | jq -r '.users[] | [.first, .last] | @csv'
        "Stevie","Wonder"
        "Michael","Jackson"
        

        第一个表达式.users[] 将对象从最外层数组中取消嵌套,如问题中给出的代码所示。下一个表达式 [.first, .last] 为每个输入对象创建一个新数组,最后一个表达式使用内置函数 @tsv@csv 将所有输入数组打印为制表符分隔和逗号分隔值。

        打印为 JSON 值

        同样,可以再次构造 JSON 值,如果您只想保留字段的子集,这很有趣:

        $ cat file.json | jq -c '.users[] | {first}'
        {"first":"Stevie"}
        {"first":"Michael"}
        

        【讨论】:

          【解决方案6】:

          虽然如果 key,value 是字符串,上述两个答案都可以正常工作,但我遇到了附加字符串和整数的情况(使用上述表达式的 jq 错误)

          要求:在json下面构造一个url

          pradeep@seleniumframework>curl http://192.168.99.103:8500/v1/catalog/service/apache-443 | jq .[0]
            % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                           Dload  Upload   Total   Spent    Left  Speed
          100   251  100   251    0     0   155k      0 --:--:-- --:--:-- --:--:--  245k
          {
            "Node": "myconsul",
            "Address": "192.168.99.103",
            "ServiceID": "4ce41e90ede4:compassionate_wozniak:443",
            "ServiceName": "apache-443",
            "ServiceTags": [],
            "ServiceAddress": "",
            "ServicePort": 1443,
            "ServiceEnableTagOverride": false,
            "CreateIndex": 45,
            "ModifyIndex": 45
          }
          

          解决方案:

          curl http://192.168.99.103:8500/v1/catalog/service/apache-443 |
          jq '.[0] | "http://" + .Address + ":" + "\(.ServicePort)"'
          

          【讨论】:

          • 请注意,不需要转义右括号,并且会出错。
          • @nymo:这不是逃避。 \(...) 是字符串插值。在这里它将数字 .ServicePort 转换为字符串。可以使用插值来代替 + 标志,以缩短此解决方案。
          【解决方案7】:

          这将产生一个名称数组

          > jq '[ .users[] | (.first + " " + .last) ]' ~/test.json
          
          [
            "Stevie Wonder",
            "Michael Jackson"
          ]
          

          【讨论】:

            【解决方案8】:

            通过做这样的事情,我已经非常接近我想要的了

            cat my.json | jq '.my.prefix[] | .primary_key + ":", (.sub.prefix[] | "    - " + .sub_key)' | tr -d '"' 
            

            它的输出与 yaml 非常接近,我通常可以毫无问题地将其导入其他工具。 (我仍在寻找一种方法来基本导出输入 json 的子集)

            【讨论】:

            • 在我的情况下这种工作,只需删除 | tr -d '"' 在末尾,并在 jq 中添加 -r 选项。
            猜你喜欢
            • 2020-12-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-28
            • 2021-01-16
            • 1970-01-01
            • 2020-05-23
            相关资源
            最近更新 更多