您的总体要求尚不清楚,但如果您确实想以您建议的方式更新任意 JSON 文本,您可能需要考虑使用 walk。不过,为了简单起见,我假设您只是拥有一组您所展示的对象。
让我们从将 TRUE/FALSE 更改为 true/false 的简单任务开始。这可以直接完成如下:
map( map_values(if . == "TRUE" then true
elif . == "FALSE" then false
else .
end) )
但是由于您的“至少一个“商店”设置为“真””的要求,定义一个辅助功能会很有帮助:
def toboolean:
if . == "TRUE" then true
elif . == "FALSE" then false
else .
end;
所以第一个任务可以通过以下方式完成:
map(map_values(toboolean))
现在我们可以开始了。假设您的 jq 有any/2,并且根据您的总体要求的一种解释,我们可以这样写:
map( if any( to_entries[];
(.key|startswith("Shop")) and .value=="TRUE" )
then map_values(toboolean)
else .
end)
或者如果只更改“Shop”值:
map( if any( to_entries[];
(.key|startswith("Shop")) and .value=="TRUE" )
then with_entries( if .key|startswith("Shop")
then .value |= toboolean
else .
end)
else .
end)
如果你的jq没有any/2,那么请考虑升级;如果这不是一个选项,您可以使用reduce 编写自己的(低效)版本。
使用when/2
上面的解决方案可以使用泛型函数when/2进行精简,定义为:
def when(filter; action): if filter//null then action else . end;
例如,上面的八行解决方案变成了这个四行,一旦熟悉了when/2,它可能也更容易阅读:
map( when( any( to_entries[];
(.key|startswith("Shop")) and .value=="TRUE" );
with_entries( when( .key|startswith("Shop");
.value |= toboolean) ) ))