Sample file.yml
:
---
- foo: bar
bing:
- bong
- bang
people:
- { name: pin, nicknames: ['pin', 'first'] }
- { name: deb, nicknames: ['deb'] }
- { name: roger, nicknames: ['roger'] }
- { name: kenny, nicknames: ['kenny'] }
- { name: annie, nicknames: ['annie'] }
I'm trying to use yq to sort people
objects by name
, except for pin
which should stay first.
Desired output:
---
- foo: bar
bing:
- bong
- bang
people:
- { name: pin, nicknames: ['pin', 'first'] }
- { name: annie, nicknames: ['annie'] }
- { name: deb, nicknames: ['deb'] }
- { name: kenny, nicknames: ['kenny'] }
- { name: roger, nicknames: ['roger'] }
❯ yq -V
yq (https://github.com/mikefarah/yq/) version v4.31.2
I got as far as slicing and sorting but that only prints the sorted slice:
❯ yq '.[].people.[1:] | sort_by(.name)' file.yml
- {name: annie, nicknames: ['annie']}
- {name: deb, nicknames: ['deb']}
- {name: kenny, nicknames: ['kenny']}
- {name: roger, nicknames: ['roger']}
Not sure how to get the rest back in, or if I'm even on the right track.
❯ yq '.[].people.[1:] | sort_by(.name)' file.yml
Actually, changing only |
to |=
in order to update the array slice while retaining the original context, should do the job (and it indeed does with kislyuk/yq). With mikefarah/yq, however, the array for some reason is returned unsorted:
yq '.[].people.[1:] |= sort_by(.name)' file.yml
---
- foo: bar
bing:
- bong
- bang
people:
- {name: pin, nicknames: ['pin', 'first']}
- {name: deb, nicknames: ['deb']}
- {name: roger, nicknames: ['roger']}
- {name: kenny, nicknames: ['kenny']}
- {name: annie, nicknames: ['annie']}
So, instead, you could do it manually by slicing off the first item, then re-adding it to the independently sorted array slice:
yq '.[].people |= .[:1] + (.[1:] | sort_by(.name))' file.yml
---
- foo: bar
bing:
- bong
- bang
people:
- {name: pin, nicknames: ['pin', 'first']}
- {name: annie, nicknames: ['annie']}
- {name: deb, nicknames: ['deb']}
- {name: kenny, nicknames: ['kenny']}
- {name: roger, nicknames: ['roger']}