3

This is probably related to another question I posted: yq (GO/Mike Farah) sort all arrays recursively?

Mike Farah's yq provides documentation for making arrays unique but I'm having trouble figuring how to apply that to lists that are nested deeper

Input

classes:
  driver:
    fields:
      - height
      - age
      - age
  vehicle:
    fields:
      - model
      - model
      - color
      - year

Desired output

classes:
  driver:
    fields:
      - age
      - height
  vehicle:
    fields:
      - color
      - model
      - year

Naively trying to globally uniqify

cat to_sort.yaml | yq 'unique'                     

Error: Only arrays are supported for unique

And if it takes arguments, I don't know what to provide. I don't want to just sort one explicit path, but I did try this:

 cat to_sort.yaml | yq 'unique(.classes.driver.fields)'

Error: Bad expression, please check expression syntax

I have seen some yq examples where one has to do a select operation first, but I don't know what to try in this case.

Mark Miller
  • 3,011
  • 1
  • 14
  • 34

2 Answers2

3
 yq e '(... | select(type == "!!seq")) |= unique' input

Will recursively loop over all the items, and select() those of type !!seq

Then update (|=) those with unique:

Result from provided input:

classes:
  driver:
    fields:
      - height
      - age
  vehicle:
    fields:
      - model
      - color
      - year

0stone0
  • 34,288
  • 4
  • 39
  • 64
1

You have to first traverse there, then update the array (here, using the update |= operator).

Either one after another:

yq '
  .classes.driver.fields |= unique
  | .classes.vehicle.fields |= unique
' to_sort.yaml

Or both at once:

yq '
  (.classes.driver.fields, .classes.vehicle.fields) |= unique
' to_sort.yaml

Both output

classes:
  driver:
    fields:
      - height
      - age
  vehicle:
    fields:
      - model
      - color
      - year
pmf
  • 24,478
  • 2
  • 22
  • 31
  • Thats not really 'recursively', rather just defining the path yourself.. – 0stone0 Sep 16 '22 at 15:54
  • 1
    Oh, I missed that (as it was only in the title, not in the description). Updating... – pmf Sep 16 '22 at 15:55
  • Ok, I'm learning already. Apologies for misusing "recursively". Maybe what I meant to say is that I want to be able to apply this action to any arrays in the document. – Mark Miller Sep 16 '22 at 15:56
  • 1
    Please consider 0stone0's [answer](https://stackoverflow.com/a/73747461/2158479) as it is exactly what I was about to turn this into. – pmf Sep 16 '22 at 16:03