1

I have the following JSON:

{
  "LaunchTemplates": [
    {
      "LaunchTemplateName": "bla-99",
      "CreateTime": "2022-12-13T13:40:33+00:00"
    },
    {
      "LaunchTemplateName": "abcabc",
      "CreateTime": "2022-12-13T09:58:14+00:00"
    },
    {
      "LaunchTemplateName": "bla-34",
      "CreateTime": "2022-12-13T13:58:56+00:00"
    },
    {
      "LaunchTemplateName": "bla-222",
      "CreateTime": "2022-12-11T13:58:56+00:00"
    },
    {
      "LaunchTemplateName": "bla-233",
      "CreateTime": "2022-12-10T13:58:56+00:00"
    }
  ]
}

I want to filter the JSON and print the oldest templates after filtering. I have the following jq query that prints the template names after filtering:

file.json | jq  '.LaunchTemplates[].LaunchTemplateName|select(startswith("bla"))'

Output:

bla-99
bla-34
bla-222
bla-233

Now i want to add more logic to the query, and do something like that: If the number of bla lines is bigger than 3, then print the oldest bla lines (according to the date field). In my case, the output should be:

bla-233

Is that possible with jq or other shell commands? If so, how?

Supertwister
  • 105
  • 1
  • 1
  • 8
  • What do you mean with "bigger than 2"? How is 222 bigger than 2, but 990is not? Or do you just want the last 2 hits? – knittl Dec 13 '22 at 20:07
  • I mean the amount of elements. For example, i have 5 templates, so the output will contain the oldest 3 templates. – Supertwister Dec 13 '22 at 20:09
  • So anything but the first two elements? "1,2,3,4,5,6" gives you "3,4,5,6"? "1,2,3,4" gives "3,4". What give "1,2" or "1,2,3"? Your text states "will contain the oldest 3 templates", but the output only contains 2 lines? – knittl Dec 13 '22 at 20:10
  • No. I want to count the number of templates that start with 'bla'. Ignore what appears after the 'bla' (it can be letters or other signs). I just want to count how many elements i have in the array after filtering, and then print the oldest elements. – Supertwister Dec 13 '22 at 20:22
  • I'll do that. Sorry for the mess. – Supertwister Dec 13 '22 at 20:30
  • @knittl, done. I hope it's clear now. – Supertwister Dec 13 '22 at 20:36
  • "drop the oldest bla lines" – "output should be bla-233". But bla-233 is the _oldest_ template and should be dropped (according to the text). Yet, according to the example it should be in the output. Please make up your mind whether you want to drop or keep the oldest entries. What happens now if there are fewer lines? Previouly the question stated that no output should be generated in that case, does that still hold? – knittl Dec 13 '22 at 20:41
  • Yes, I agree that I wasn't clear (I'm going to use the output for deletion. That's why I wrote drop). I've just edited the text again. Sorry again for the mess. – Supertwister Dec 13 '22 at 20:45

1 Answers1

1

If you are only interested in the last two elements (and ignoring the fact that the input in the question is invalid JSON):

.LaunchTemplates
| sort_by(.CreateTime)
| map(.LaunchTemplateName|select(startswith("")))[:-3]
| reverse[]
  • sort_by(.CreateTime) sorts ascending by the CreateTime property.
  • map(.LaunchTemplateName|select(startswith("bla")) maps the input array to an array containing only the template names with a "bla" prefix.
  • [:-3] slices the input array to drop the last 3 elements (i.e. dropping the 3 newest elements.
  • reverse[] reverses the array and streams its elements.

Output:

"bla-222"
"bla-233"
knittl
  • 246,190
  • 53
  • 318
  • 364