2

I'm new to jq, but I'm confident it can help my workflow once I figure it out. I have been provided with some data that looks something like the below:

{
  "parent_name1": {
    "parent_count": 2000, 
    "fields": {
      "field1_count": 2000, 
      "field2_count": 2000,
      ...
      "fieldx_count": 20
    }
  }, 
  "parent_name2": {
    "parent_count": 1000, 
    "fields": {
      "field1_count": 1000, 
      "field2_count": 1000,
      ...
      "fieldx_count": 100
    }
  },
  "parent_namex": {
    ...
  }
}

There are two things I want to do:

  1. Select a specific parent name and have it display the name and all children values (count, and all field counts).
  2. Show all parent names where field counts are less than the total parent count.

I am close with the below commands, but they still aren't quite where I want them to be:

jq '."parent_name1"'

will give me "parent_count", "fields" and all of the field counts, but does not provide the parent name.

This:

jq '.[] | {parent_count: .parent_count, fields: .fields[]} | select(.fields < .parent_count)'

returns "parent_count" and a total field count, but not the parent name or the counts for the individual fields. I know the summed field count comes from {fields: .fields[]}, but I cannot find any way to get even remotely close to what I want without that.

1
  • Does this work for #1? $ jq '{"parent_name1" : getpath(["parent_name1"])}' /tmp/foo.json { "parent_name1": { "parent_count": 2000, "fields": { "field1_count": 2000, "field2_count": 2000, "fieldx_count": 20 } } } – Joe Casadonte May 13 at 20:32
2

As you have noticed, using

jq '.parent_name2' file

or, with the section's name given as a parameter,

jq --arg parent 'parent_name2' '.[$parent]' file

would not output a JSON object with parent_name2 as the top-level key.

However, we may create an object with the needed data:

$ jq --arg parent 'parent_name2' '{($parent): .[$parent]}' file

Given a sanitized variant of your example document, this would produce

{
  "parent_name2": {
    "parent_count": 1000,
    "fields": {
      "field1_count": 1000,
      "field2_count": 1000,
      "fieldx_count": 100
    }
  }
}

In your second query (only a single query per question in the future please), you presumably ask about the top-level key names corresponding to objects whose .parent_count value is less than the sum of the corresponding .fields counts.

jq -r 'del(.[] | select(.parent_count >= (.fields | add ))) | keys[]' file

This deletes all sections where the sum of the .fields values are greater or equal to the .parent_count value. It then extracts the top-level key names of all sections that are left.

1
  • Thank you for the detailed response! And my apologies for having two queries, I'll be sure to only include one in future questions. The first query you provided works great, thank you! For the second query, would it be possible to have it also output the relevant field counts? (i.e. for each remaining parent_name also list the parent_count and field_counts? This would allow me to know exactly which fields I need to investigate. – Bryce M May 17 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.