【问题标题】:jq - add preffix to values on arrayjq - 为数组中的值添加前缀
【发布时间】:2021-04-26 06:05:14
【问题描述】:

输入json:

[
{
  "login": "u1",
  "name": "u1",
  "role": "User",
  "groups": [
    {
      "id": "1234",
      "name": "G1"
    },
    {
      "id": "1235",
      "name": "G2"
    }
  ],
  "created": "2020-05-11 11:06"
},
{
  "login": "u2",
  "name": "u2",
  "role": "User",
  "groups": null,
  "created": "2020-05-11 11:06"
}
]

我使用以下过滤器来获取他们所属的用户和组:

$ jq -r '
  .[]
  | [.login,
     .name,
     ( if .groups == null 
       then "grp:-" 
       else (del(.groups[]
             | select(.name=="All Users"))
            | [.groups[].name] | join("|")) 
       end )]
  | @tsv' json
u1      u1      G1|G2
u2      u2      grp:-

如何为每个找到的组添加grp: 前缀? 预期输出为:

u1      u1      grp:G1|grp:G2
u2      u2      grp:-

【问题讨论】:

    标签: arrays json export-to-csv jq


    【解决方案1】:

    使用+ 连接字符串:

    jq -r '.[]
           | [.login,.name,(
               if .groups == null
               then "grp:-"
               else (
                   del(.groups[] | select(.name=="All Users"))
                   | ["grp:" + .groups[].name]
    #                 ~~~~~~~~
                   | join("|")
               )
               end
          )]
          | @tsv' 
    

    您甚至可以避免指定“grp:”两次,但您也需要从 then 分支返回一个数组:

    jq -r '.[]
           | [.login, .name, (
               (
                   if .groups == null
                   then ["-"]
                   else (
                       del(.groups[] | select(.name=="All Users"))
                       | [.groups[].name]
                   )
                   end
               )
               | map("grp:" + .)
               | join("|")
           )]
           | @tsv'
    

    更新: 从 peak 获得灵感我想这会产生你想要的输出:

    jq -r '.[]
            | .groups //= []
            | del(.groups[] | select(.name=="All Users"))
            | .groups[0] //= {name: "-"}
            | [.login, .name, ( ["grp:" + (.groups[].name)] | join("|") ) ]
            | @tsv'
    

    【讨论】:

    • 我发现了一个问题,当组数组只有“所有用户”时,我删除了它——然后“grp:-”我得到了空输出。这里是这种情况的示例输入: [{"login":"u1","name":"u1","role":"User","groups":[{"id":"1234","name" :"G1"},{"id":"1235","name":"G1"}],"created":"2020-05-11 11:06"},{"login":"u2", "name":"u2","role":"User","groups":null,"created":"2020-05-11 11:06"},{"login":"u3","name" :"u3","role":"User","groups":[{"id":"1234","name":"All Users"}],"created":"2020-05-11 11: 06"}]
    • @Chris - 我刚才发布的变体解决方案是否从您的角度适当地处理了边缘情况?
    • @peak:我对其进行了一些修改,我认为它现在产生了预期的输出。谢谢你的想法。
    【解决方案2】:

    这里是已经给出的解决方案的一个稍微短一些并且可能更整洁的变体。它具有处理本页其他地方评论中提到的边缘情况的优势。

      .[]
      | .groups //= [{name: "-"}]
      | [.login,
         .name,
         (del(.groups[] | select(.name=="All Users"))
         | ["grp:" + (.groups[].name)] | join("|")) 
        ]
      | @tsv
    

    还是比较简单

      .groups //= [{name: "-"}]
      | .groups |= map(select( .name != "All Users") )
      | [.login, .name,
         (.groups | map("grp:" + .name) | join("|")) ]
      | @tsv```
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      • 2017-06-17
      • 2021-11-03
      • 2011-11-28
      相关资源
      最近更新 更多