如何在多个条件下使用 jq try?

How to use jq try with multiple conditions like a case?

我需要在单列中输出字段 A 的值(如果它不为空)或字段 B 的值(如果它不为空)或无(如果 A 和 B 都为空)。

当我刚刚提交 A 进行测试时,我写了这个工作正常

try .fieldA catch ""

但是现在我需要在 A 为 null 的情况下获取字段 B 我尝试了这些,但没有任何效果

try .fieldA catch try .fieldB catch "" => this only returned empty values ever
try (.fieldA or .fieldB) catch ""  => this one outputs true or false, 2 resultst instead of 1
try (.fieldA,.fieldB) catch ""  => this one outputs both A and B if both are not nulll, so 2 resultst instead of 1

我想尝试在第一个结果不为空时停止评估

谢谢

使用 alternate operator //,如果第一个是 nullfalse,则使用第二个选项,而 empty 则为“无”结果。 如果访问任何字段可能会失败,请在这些字段上另外使用 optional operator ?

{
  "fieldA": "A1 present",
  "fieldB": "B1 present",
  "fieldC": "irrelevant"
}
{
  "fieldB": "B2 present",
  "fieldC": "irrelevant"
}
{
  "fieldA": "A3 present",
  "fieldC": "irrelevant"
}
{
  "fieldC": "irrelevant"
}
jq '.fieldA // .fieldB // empty'
"A1 present"
"B2 present"
"A3 present"

Demo


解决@peak 的“警告”:如果您想捕获具有显式布尔值 false 的文件,而如果它丢失或明确设置为 null,则不捕获它,您可以使用 values 仅选择 non-null 值,并使用 first 检索给定备选项流中存在的第一个值:

{
  "fieldA": "A1 present",
  "fieldB": "B1 present",
  "fieldC": "irrelevant"
}
{
  "fieldA": false,
  "fieldB": "B2 present",
  "fieldC": "irrelevant"
}
{
  "fieldA": null,
  "fieldB": "B3 present",
  "fieldC": "irrelevant"
}
{
  "fieldB": "B4 present",
  "fieldC": "irrelevant"
}
{
  "fieldC": "irrelevant"
}
jq 'first(.fieldA, .fieldB | values)'
"A1 present"
false
"B3 present"
"B4 present"

Demo

使用此方法,无需提供明确的 empty 大小写。但是,如果您想要默认回退,请将其添加为流中的最后一项,例如first(.fieldA, .fieldB, "" | values).

jq 的 // 运算符语义相当复杂 (*) 特别是,在评估 E // F 时,E 是 nullfalse 或空流之间没有区别。

此外,给定一个对象作为输入,表达式 .x 的计算结果将是 JSON 值 null 如果键“x”是显式的 如果键“x”根本不存在,则指定为 null

因此,假设一个对象已作为输入, 如果我们想要 .fieldA 如果 .fieldA 是 non-null, 如果 .fieldB 为 non-null,则为 .fieldB,否则为 .fieldB 否则字符串“缺失”,那么我们将不得不按照以下行写一些东西:

  if   .fieldA != null then .fieldA
  elif .fieldB != null then .fieldB
  else "missing"
  end

只需将“缺失”替换为empty即可实现原问题中所述的objective。


(*) 查看 jq FAQ 了解完整详情。