jsonjq

How to retrieve the next key value pair with jq when I know the previous value only


I would like to retrieve the next key value pair if I know the previous value one from the JSON file like below:

{
   "metadata":{
      "secretSchema":"3.0",
      "tenant":"MyTenantName"
   },
   "globalSecrets":[
      {
         "secretName":"secretName1",
         "secretValue":"secretValue1"
      },
      {
         "secretName":"secretName2",
         "secretValue":"secretValue2"
      },
      {
         "secretName":"secretName3",
         "secretValue":"secretValue3"
      },
      {
         "secretName":"secretName4",
         "secretValue":"secretValue4"
      },
      {
         "secretName":"secretName5",
         "secretValue":"secretValue5"
      },
      {
         "secretName":"secretName6",
         "secretValue":"secretValue6"
      },
      {
         "secretName":"secretName7",
         "secretValue":"secretValue7"
      }
   ]
}

I only know the value of the secretValue5 and would like to retrieve the secretName5 value and the next one (secretName6 and secretValue6)

I tried the following command:

.globalSecrets[] | to_entries | while(. != []; .[1:])[:2] | select(first.value == "secretValue5") | first.key, first.value, last.key, last.value

But the result is

secretValue
secretValue5
secretValue
secretValue5

The result expected is

secretName5
secretValue5
secretName6
secretValue6

I posted a similar question in this post but with another JSON file with the above command and it's working fine, but not from the above JSON file.


Solution

  • This is based on the previous approach which was about finding the next key-value pair in an object. In the current case, however, the question is about finding the next item in an array (which, in contrast to the previous case, has an explicit order), while the array items are objects, and the output is two values from the found object (rather than their key-value pairs). Thus, you don't need to_entries, and in consequence any reference to .key or .value. Just work directly on the array .globalSecrets and the fields of its items (.secretName and .secretValue):

    .globalSecrets | while(. != []; .[1:])[:2]
    | select(first.secretValue == "secretValue5")
    | first.secretName, first.secretValue, last.secretName, last.secretValue
    
    secretName5
    secretValue5
    secretName6
    secretValue6
    

    Demo