title: How can I delete all keys that don't match certain names with JQ?
body: <p>I have a huge JSON file with lots of stuff I don't care about, and I want to filter it down to only the few keys I care about, preserving the structure. I won't bother if the same key name might occur in different paths and I get both of them. I gleaned something very close from the answers to <a href="https://stackoverflow.com/questions/39500608/remove-all-null-values">this question</a>, it taught me how to delete all properties with certain <em>values</em>, like all null values:</p>
  <pre><code>del(..|nulls)
  </code></pre>
  <p>or, more powerfully</p>
  <pre><code>del(..|select(. == null))
  </code></pre>
  <p>I searched high and low if I could write a predicate over the name of a property when I am looking at a property. I come from XSLT where I could write something like this:</p>
  <pre><code>del(..|select(name|test(&quot;^(foo|bar)$&quot;)))
  </code></pre>
  <p>where name/1 would be the function that returns the property name or array index number where the current value comes from. But it seems that jq lacks the metadata on its values, so you can only write predicates about their value, and perhaps the type of their value (that's still just a feature of the value), but you cannot inspect the name, or path leading up to it?</p>
  <p>I tried to use paths and leaf_paths and stuff like that, but I have no clue what that would do and tested it out to see how this path stuff works, but it seems to find child paths inside an object, not the path leading up to the present value.</p>
  <p>So how could this be done, delete everything but a set of key values? I might have found a way <a href="https://stackoverflow.com/questions/42635140/jq-recursively-delete-all-keys-that-match-a-given-pattern">here</a>:</p>
  <pre><code>walk(
    if type == &quot;object&quot; then 
      with_entries(
        select(    ( .key |test(&quot;^(foo|bar|...)$&quot;) )
               and ( .value != &quot;&quot; )
               and ( .value != null ) )
      )
    else 
      . 
    end
  )
  </code></pre>
  <p>OK, this seems to work. But I still wonder it would be so much easier if we had a way of querying the current property name, array index, or path leading up to the present item being inspected with the simple recusion ..| form.</p>