如何不使用jq跳过包含null的数组?

时间:2018-11-30 08:15:30

标签: null iteration jq

我要处理此数据

{
  "results": [
    {
      "headword": "binding",
      "senses": [
        {
          "definition": [
            "a promise, agreement etc that must be obeyed"
          ]
        }
      ]
    },
    {
      "headword": "non-binding",
      "senses": [
        {
          "definition": [
            "a non-binding agreement or decision does not have to be obeyed"
          ],
          "examples": [
            {
              "text": "The industry has signed a non-binding agreement to reduce pollution."
            }
          ]
        }
      ]
    }
  ]
}

进入此

{
  "headword": "binding",
  "definition": "a promise, agreement etc that must be obeyed",
  "examples": null
}
{
  "headword": "non-binding",
  "definition": "a non-binding agreement or decision does not have to be obeyed",
  "examples": "The industry has signed a non-binding agreement to reduce pollution."
}

此命令

cat data.json | jq '.results[] | {headword: .headword, definition: .senses[].definition[], examples: .senses[].examples[].text}'

出现错误,提示“无法遍历null”

为了克服这个问题,该命令使用'。[]?'过滤器

cat data.json | jq '.results[] | {headword: .headword, definition: .senses[].definition[], examples: .senses[].examples[]?.text}'

但这仅输出

{
  "headword": "non-binding",
  "definition": "a non-binding agreement or decision does not have to be obeyed",
  "examples": "The industry has signed a non-binding agreement to reduce pollution."
}

那么,如何遍历null而不跳过数组?

2 个答案:

答案 0 :(得分:2)

使用if / else语句可能会有所帮助。

jq '.results[] | {
    headword,
    definition: .senses[0].definition[0],
    examples: (if .senses[0].examples then .senses[0].examples[0].text else null end)
}' data.json

答案 1 :(得分:1)

正如@oguzismail隐式指出的那样, 假设感官数组只有一个元素 是有风险的,特别是正如名称选择所暗示的那样 可以预料的是,每个词都可能具有多种含义。 可以对.examples进行类似的观察,但是 如果.examples元素不止一个,Q并没有清楚该怎么办。

因此,在下文中,我将选择一种安全的方法, 因为可以轻松调整它以满足更多特定要求。

.results[]
| { headword }
  + (.senses[]
     | { definition: .definition[0],
         examples: (if has("examples")
                    then [.examples[].text]
                    else null end) } )