Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON key-globbing

Tags:

json

key

glob

jq

On the jq manual page there are a few examples of output formatting, particularly some shortcuts for when you want to just echo exactly what was in the input JSON.

What if I want to echo exactly what was in the input, but only for keys that match a certain pattern?

For example, given input like so ...

[
{"Name":"Widgets","Size":10,"SymUS":"Widg","SymCN":"Zyin","SymJP":"Kono"},
{"Name":"Blodgets","Size":400,"SymUS":"Blodg","SymAU":"Blod","SymJP":"Kado"},
{"Name":"Fonzes","Size":11,"SymRU":"Fyet","SymBR":"Foao"}
]

Say I want to select all objects where the Name ends in "ets" and then display the Name and all attributes of the form Sym*. All I know about those attributes is that there will be one or more per JSON object, and the names have the format Sym followed by a two-letter ISO country code.

I would like to just do this:

jq '.[] | select(.Name | endswith("ets")) | {Name, Sym*}'

but that's not a thing.

Is this just not something jq is designed to handle in a single operation? Should I do a first pass through the file to collect all the possible keys and then list them all explicitly via a slurpfile?

like image 712
dg99 Avatar asked May 05 '26 00:05

dg99


1 Answers

The key to a simple solution to the problem is to_entries, as described in the online manual. With your example data, the following filter produces the output shown below, in accordance with what I understand to be the expectations:

.[]
| select(.Name | test("ets$"))
| {Name} + (to_entries | map(select(.key|test("^Sym"))) | from_entries)

You might want to refine the regex tests, and/or make other minor adjustments.

Output:

{
  "Name": "Widgets",
  "SymUS": "Widg",
  "SymCN": "Zyin",
  "SymJP": "Kono"
}
{
  "Name": "Blodgets",
  "SymUS": "Blodg",
  "SymAU": "Blod",
  "SymJP": "Kado"
}
like image 180
peak Avatar answered May 06 '26 14:05

peak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!