给定一个数组中的键的输入json字符串,返回一个对象,其中只包含在原始对象和输入数组中具有键的条目。
我有一个解决方案,但我认为它并不优雅({($k):$input[$k]}
感觉特别笨拙...),这是一个学习的机会。
jq -n '{"1":"a","2":"b","3":"c"}' \
| jq --arg keys '["1","3","4"]' \
'. as $input
| ( $keys | fromjson )
| map( . as $k
| $input
| select(has($k))
| {($k):$input[$k]}
)
| add'
有什么办法能把这里清理干净吗?
我觉得Extracting selected properties from a nested JSON object with jq是一个很好的起点,但是我不能让它工作。
6条答案
按热度按时间a64a0gku1#
内部检查解决方案:
abithluo2#
您可以使用此筛选器:
js5cn81o3#
大部分时间由内部操作人员工作;然而,我发现内部运算符有副作用,有时它选择的键不是所需的,假设输入是
{ "key1": val1, "key2": val2, "key12": val12 }
,并选择inside(["key12"])
,它将同时选择"key1"
和"key12"
如果需要精确匹配,请使用in运算符:这样将仅选择
.key2
和.key12
因为in运算符只检查对象中的键(或者数组中的索引
exists?
),所以这里它必须用对象语法编写,将所需的键作为键,但值无关紧要; in运算符的使用对于此目的并不是一个完美的方法,我希望看到Javascript ES6包括API的反向版本,以实现为jq内置https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
检查
.key
项是否为数组中的included?
rdlzhqv94#
以下是一些附加说明
对于输入对象
{"key1":1, "key2":2, "key3":3}
,我想删除所有不在所需键["key1","key3","key4"]
集合中的键with_entries
会将{"key1":1, "key2":2, "key3":3}
转换成下列索引键值组的数组,并将select陈述式Map到数组上,然后将产生的数组转换回对象。下面是
with_entries
语句中的内部对象。然后我们可以从这个数组中选择符合我们标准的键。
这就是神奇的地方......下面我们来看看这个命令中间发生了什么。下面的命令将展开的值数组转换成一个对象列表,我们可以从中进行选择。
这将产生以下结果
with entries命令可能有点棘手,但它很容易记住,因为它需要一个过滤器,定义如下
这与
问题的另一个让人困惑的部分是
==
右侧的多个匹配项考虑下面的命令,我们看到输出是所有左手列表和右手边列表的外部产生。
如果该 predicate 在select语句中,则当 predicate 为真时,我们保留输入。注意,您也可以在此处复制输入。
vc6uscn95#
Jeff的答案有两个不必要的低效问题,假设使用
--argjson keys
而不是--arg keys
,则可通过以下方式解决这两个问题:如果你的jq有
IN
,那就更好了:56lgkhnf6#
如果确定输入数组中的所有键都存在于原始对象中,则可以使用对象构造快捷方式。
数字应该用引号引起来,以强制
jq
将它们解释为键而不是文字。如果键不像数字,则不需要引号:添加一个不存在的键将产生一个空值,这不太可能是OP想要的:
但是可以过滤掉那些:
虽然这个答案没有收到OP要求的有效输入json数组,但我发现它对于过滤一些你知道存在的键很有用。
以下是一个示例用例:从JWT中获取
aud
和iss
。在这种情况下,jq '{aud, iss}'
非常简洁。