【问题标题】:JQ create field only if it existsJQ仅在存在时才创建字段
【发布时间】:2017-06-08 23:24:03
【问题描述】:

在 jq 中,如何确保仅在被检查的对象中存在 k,v 时才创建它?例如,假设我有一个像这样的对象:

{
 "student":{
    "name": "george",
    "age" : "15",
    "quote": "Hello I am George"
    }
 }

我做cat text.txt | jq '{name: .student.name, quote: .student.quote}' 创建:

  {
   "name": "george",
   "quote": "Hello I am George"
   }

但是,有些条目是不完整的,我不想写一个空的K,V。假设我得到:

{
 "student":{
    "name": "Shirley"
  }
} 

使用上面的当前 jq 将创建:

 {
  "name": "Shirley",
  "quote": " ",
  }

有没有办法告诉 jq 只创建 'quote' 键,如果它存在(即不为空)?或者更一般地说,只有当它们存在于被检查的对象中时才创建所有键。

【问题讨论】:

  • 你能更新一下实际使用的过滤器吗?
  • 添加了过滤器。干杯。
  • 事物是如何被创造出来的???

标签: json filter key jq


【解决方案1】:

如果您提前知道键是什么并且它们是直接属性,则只需构建所需键的数组并检查对象是否包含这些键。

$ jq --argjson keys '["name","quote"]' '
def copy_keys($keys): . as $o
    | reduce $keys[] as $k ({}; if ($o|has($k)) then .[$k] = $o[$k] else . end)
    ;
.student | copy_keys($keys)' text.txt

但是您提出问题的方式是,“或者更一般地说,仅当它们存在于被检查的对象中时才创建所有字段,”您只需要对象中的所有键,只要它有一把钥匙。为什么不直接获取对象?

$ jq '.student' text.txt

【讨论】:

    【解决方案2】:

    这是对象添加非常方便的地方,尤其是因为$obj + null 产生$obj(如果$obj 是一个JSON 对象):

    .student |  {name} + if has("quote") then {quote} else null end
    

    或等效:

    def maybe(k): if has(k) then {(k): .[k]} else null end;
    .student |  {name} + maybe("quote")
    

    一种稍微不同的方法,具有细微不同的语义,将是:

    .student |  {name} + ((select(.quote) | {quote}) // null)
    

    当然,其他变化也是可能的。

    【讨论】:

    • 您好 - 或者有一种方法可以在新对象上使用 del 函数。假设我有一个字段的映射,这些字段或可能不是 null,然后传递给 del 函数以删除新的 null 值?这可能吗?
    • 我认为答案是“是”,但如果您想要更具体的答案,则必须更具体一些。也许最好问一个新的 SO q?
    猜你喜欢
    • 2022-08-09
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2019-08-09
    • 2018-04-19
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多