Max
Max

Reputation: 3

How to use yq on multiple documents, selected by content not by index

If I have multiple documents in one file (example.yaml), like in a k8s manifest:

kind: Service
---
kind: Deployment

Is there a way I can select documents other than by their numeric index?

My final command is like this to add alpine to the deployment:

yq '. | ( select(documentIndex==1) | .spec += {"image":"alpine"}), select(documentIndex!=0)' example.yaml
kind: Service
---
kind: Deployment
spec:
  image: alpine

But if someone flipped the sequence of documents or there was an extra document it would break.

Is there a "better" way to achieve this. (Obviously this is a super simple example and a real manifest can contain hundreds of documents and even some for the same kind. so I'd need something like kind=="Deployment" & name="nginx")

Upvotes: 0

Views: 23

Answers (1)

pmf
pmf

Reputation: 36088

You can select by any filter you want, e.g. by matching some parts against some literals, and then just modify the selected items while still keeping the top-level context to output all documents:

yq 'select(.kind == "Deployment").spec.image = "alpine"' example.yaml
kind: Service
---
kind: Deployment
spec:
  image: alpine

For extended selectors, just use boolean operators like and. e.g. .kind == "Deployment" and .name == "nginx"

Upvotes: 0

Related Questions