jq - Include element only if present - Stack Overflow

I am implementing a program accessing a REST API, which can be filtered server-side by passing in a jq-

I am implementing a program accessing a REST API, which can be filtered server-side by passing in a jq-statement. My issue is with writing a jq filter that includes an element called "forecast.forecast" in the output only if it has content in the input, and also filters the content.

Here is an example of the input with forecast being present:

{
   "result":{
      "forecast":{
         "solar":{
            "scale":0.5792918589105848,
            "today":{
               "energy":21142.72731634481,
               "complete":true
            },
            "tomorrow":{
               "energy":36320.01044880075,
               "complete":true
            },
            "dayAfterTomorrow":{
               "energy":12222.739005817713,
               "complete":false
            },
            "timeseries":[
               {
                  "ts":"2025-03-12T00:00:00+01:00",
                  "val":0
               }
            ]
         }
      },
      "siteTitle":"KOG"
   }
}

Here is an example with forecast being empty:

{
   "result":{
      "forecast":{},
      "siteTitle":"KOG"
   }
}

The "forecast" element may also be not present at all:

{
   "result":{
      "siteTitle":"KOG"
   }
}

My goal is to get only the "scale" and "energy" values from "forecast.solar", and also other elements on the same level as "forecast", such as "siteTitle".

Here an example that gives me the "siteTitle" and the "scale":

{result:{siteTitle:.siteTitle,forecast:{solar:{scale:.forecast.solar.scale}}}}

However, even if the "scale" value is not present in the input, the output contains it as null:

{
   "result":{
      "forecast":{
         "solar":{
            "scale":null
         }
      },
      "siteTitle":"KOG"
   }
}

I already tried using select to check if "forecast.solar" is present, but with what I came up with, the complete result is empty when "forecast.solar" is not present.

jq={result:{siteTitle:.siteTitle,forecast:(.forecast|select(.solar?)|{solar:{scale:.solar.scale}})}}

This returns:

jq: empty result

How does the statement need to look like to include fields like the "siteTitle", even if "forecast.solar" is not present?

I am implementing a program accessing a REST API, which can be filtered server-side by passing in a jq-statement. My issue is with writing a jq filter that includes an element called "forecast.forecast" in the output only if it has content in the input, and also filters the content.

Here is an example of the input with forecast being present:

{
   "result":{
      "forecast":{
         "solar":{
            "scale":0.5792918589105848,
            "today":{
               "energy":21142.72731634481,
               "complete":true
            },
            "tomorrow":{
               "energy":36320.01044880075,
               "complete":true
            },
            "dayAfterTomorrow":{
               "energy":12222.739005817713,
               "complete":false
            },
            "timeseries":[
               {
                  "ts":"2025-03-12T00:00:00+01:00",
                  "val":0
               }
            ]
         }
      },
      "siteTitle":"KOG"
   }
}

Here is an example with forecast being empty:

{
   "result":{
      "forecast":{},
      "siteTitle":"KOG"
   }
}

The "forecast" element may also be not present at all:

{
   "result":{
      "siteTitle":"KOG"
   }
}

My goal is to get only the "scale" and "energy" values from "forecast.solar", and also other elements on the same level as "forecast", such as "siteTitle".

Here an example that gives me the "siteTitle" and the "scale":

{result:{siteTitle:.siteTitle,forecast:{solar:{scale:.forecast.solar.scale}}}}

However, even if the "scale" value is not present in the input, the output contains it as null:

{
   "result":{
      "forecast":{
         "solar":{
            "scale":null
         }
      },
      "siteTitle":"KOG"
   }
}

I already tried using select to check if "forecast.solar" is present, but with what I came up with, the complete result is empty when "forecast.solar" is not present.

jq={result:{siteTitle:.siteTitle,forecast:(.forecast|select(.solar?)|{solar:{scale:.solar.scale}})}}

This returns:

jq: empty result

How does the statement need to look like to include fields like the "siteTitle", even if "forecast.solar" is not present?

Share Improve this question edited Mar 12 at 12:41 Robert asked Mar 12 at 11:53 RobertRobert 1571 silver badge10 bronze badges 1
  • Thank you, and sorry for not asking the question properly. I have rewritten the question to include sample JSONs directly. They are all reduced to the minimum necessary to explain/solve the issue, the actual JSON is much bigger. – Robert Commented Mar 12 at 12:42
Add a comment  | 

1 Answer 1

Reset to default 2

My goal is to get only the "scale" and "energy" values from "forecast.solar", and also other elements on the same level as "forecast", such as "siteTitle".

As you want to keep .scale and all siblings that contain .energy (IIUC), you could also just del(.timestamp) instead, then filter for values to eliminate empty results.

.result | .forecast |= (.solar | del(.timeseries) | values)

For your sample containing a non-empty .forecast, this produces

{
  "forecast": {
    "scale": 0.5792918589105848,
    "today": {
      "energy": 21142.72731634481,
      "complete": true
    },
    "tomorrow": {
      "energy": 36320.01044880075,
      "complete": true
    },
    "dayAfterTomorrow": {
      "energy": 12222.739005817713,
      "complete": false
    }
  },
  "siteTitle": "KOG"
}

For your other samples, one with no .forecast, the other one with it being an empty object, it produces

{
  "siteTitle": "KOG"
}

Demo for all three cases.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744754370a4591790.html

相关推荐

  • jq - Include element only if present - Stack Overflow

    I am implementing a program accessing a REST API, which can be filtered server-side by passing in a jq-

    10小时前
    50

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信