Michael Deardeuff
Michael Deardeuff

Reputation: 10697

jq: How to select within a nested array

I am trying to select a sub-set of an object's children in jq while keeping the outer object.

Take the example input:

{
  "head": "master",
  "hash": "ba2054c38ec68b73926acb24cd0bad61177a03d4",
  "upstream": "origin/master",
  "ahead": 1,
  "behind": 0,
  "changes": [
    {
      "name": "exe/each-package",
      "status": "updated_in_index",
      "work_tree_status": "modified",
      "index_status": "unmodified"
    },
    {
      "name": "exe/find-package",
      "status": "not_updated",
      "work_tree_status": "unmodified",
      "index_status": "modified"
    },
    {
      "name": "lib/tools/tool_support.rb",
      "status": "not_updated",
      "work_tree_status": "unmodified",
      "index_status": "modified"
    },
    {
      "name": "curses.txt",
      "status": "untracked",
      "work_tree_status": "untracked",
      "index_status": "untracked"
    },
    {
      "name": "exe/fat-stat",
      "status": "untracked",
      "work_tree_status": "untracked",
      "index_status": "untracked"
    },
    {
      "name": "exe/prefix-each-with",
      "status": "untracked",
      "work_tree_status": "untracked",
      "index_status": "untracked"
    },
    {
      "name": "notes.txt",
      "status": "untracked",
      "work_tree_status": "untracked",
      "index_status": "untracked"
    }
  ]
}

And the expected output where I have removed a subset of the changes member:

{
  "head": "master",
  "hash": "ba2054c38ec68b73926acb24cd0bad61177a03d4",
  "upstream": "origin/master",
  "ahead": 1,
  "behind": 0,
  "changes": [
    {
      "name": "exe/each-package",
      "status": "updated_in_index",
      "work_tree_status": "modified",
      "index_status": "unmodified"
    },
    {
      "name": "exe/find-package",
      "status": "not_updated",
      "work_tree_status": "unmodified",
      "index_status": "modified"
    },
    {
      "name": "lib/tools/tool_support.rb",
      "status": "not_updated",
      "work_tree_status": "unmodified",
      "index_status": "modified"
    }
  ]
}

I was able to do it like the following. But I suspect there is a more succinct way to filter the innards of a nested array, perhaps removing the duplication.

jq '. + {changes: [.changes[] | select(.status != "untracked")]}'

Upvotes: 0

Views: 752

Answers (1)

peak
peak

Reputation: 116730

More succinct can be achieved by:

.changes |= map(select(.status != "untracked"))

Upvotes: 1

Related Questions