JQ:选择具有值集值的对象

时间:2015-04-15 19:44:51

标签: jq

我有一个json对象数组,我想提取数组的一个子集,使.name字段与一组输入字符串匹配。

例如,我想完成以下任务。

jq -n '["a","b","c","d","e"] | map({name:.,foo:"bar"})' \
  | jq 'map(select(.name=="a" or .name=="c"))'

我已经提出了以下解决方案,但我对[...]add的使用似乎让我错过了一些聪明的东西。

jq -n '["a","b","c","d","e"] | map({name:.,foo:"bar"})' \
  | jq --arg name 'a c' '
      [
        ( $name | split(" ") )[] as $name
        | map( select( .name == $name ) )
        | add
      ]'

此外,此解决方案迫使我多次迭代输入数组而不是单次传递。我有什么其他想法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:3)

将所有内容移至select条件。你不需要对jq进行两次单独的调用。

$ echo '["a","b","c","d","e"]' | jq --arg names 'a c'
    'map(select(. == ($names | split(" ")[])) | { name: ., foo: "bar" })'
[
  {
    "name": "a",
    "foo": "bar"
  },
  {
    "name": "c",
    "foo": "bar"
  }
]

答案 1 :(得分:2)

ThorSummoner的观点, 这是一个不太常见的解决方案,使用 - argjson 内部 对利用shell '行为的单独行进行注释:

$ echo '["a","b","c","d","e"]' | jq --argjson wanted '["a","c"]' '
  .[]                          # break array into elements
| if ([.]|inside($wanted))     # if element is in wanted
  then {name: ., foo:"bar"}    # generate desired output
  else empty                   # otherwise generate nothing
  end
'