Reputation: 601
I have been using yq v3 to merge yaml files using the following command.
yq m <yaml_file> <yaml_file2> <yaml_file3>
The command works as outlined here
For example, let's say I have the following 3 yaml files.
training-lab-account.yml
account:
alias: training-lab-account
orgEmail: [email protected]
snsSubscriptions:
- [email protected]
network:
vpcs:
- cidr: 10.253.0.0/16
snsSubscriptions:
- [email protected]
account.yml
---
account:
snsSubscriptions:
- [email protected]
orgEmail: REQUIRED
orgAccountProvisioningEnabled: true
groups:
- name: SmileAdmins
policies:
- AdministratorAccess
- name: SmileReadOnly
policies:
- ReadOnlyAccess
network.yml
---
network:
snsSubscriptions:
- [email protected]
vpcs:
- vpcName: Main
amiPipeline: false
accountVendingMachine: false
flowlogs: true
transitGw: false
maxAzs: 3
endpoints:
gateway:
- name: s3
- name: dynamodb
interface:
- name: ssm
when I execute yq m training-lab-account.yml account.yml network.yml
, I get the following output.
account:
alias: training-lab-account
orgEmail: [email protected]
snsSubscriptions:
- [email protected]
orgAccountProvisioningEnabled: true
groups:
- name: SmileAdmins
policies:
- AdministratorAccess
- name: SmileReadOnly
policies:
- ReadOnlyAccess
network:
vpcs:
- cidr: 10.253.0.0/16
vpcName: Main
amiPipeline: false
accountVendingMachine: false
flowlogs: true
transitGw: false
maxAzs: 3
endpoints:
gateway:
- name: s3
- name: dynamodb
interface:
- name: ssm
snsSubscriptions:
- [email protected]
Basically, account.yml and network.yml are merged into training-lab-account.yml without overwriting the content in training-lab-account.yml.
yq v4 doesn't support the "m" flag to merge anymore. Actually I feel like yq@4 is a brand new piece of software and is completely different from yq@3.
Long story short, I am trying to merge using eval-all
as outlined here: yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' f1.yml f2.yml
Unfortunately, this overwrites what's in f1.yml from f2.yml - which is not how merge behaves in yq@3.
Since yq@3 is deprecated, I need to upgrade to yq@4. I would appreciate any feedback on how to replicate the merge feature from yq@3 in yq@4.
Upvotes: 1
Views: 2710
Reputation: 807
In your general example
yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' f1.yml f2.yml
f2.yml overwrites all values that exist in f1.yml. This corresponds to yq v3 behavior of yq m -ix f1.yml f2.yml
If you want to keep values from f1.yml you can simply switch the order:
yq eval-all --inplace 'select(fileIndex == 1) * select(fileIndex == 0)' f1.yml f2.yml
Note, that we switch the order in the select command but keep the order of the given filenames. This ensures that f1.yml is the file that is rewritten in-place.
I am pretty sure, you can define the order in the select command in a way that your 3 file merge also works as you want it.
Upvotes: 0
Reputation: 39638
If you give --inplace
, it writes the result to the first given file. Just drop that parameter.
Edit: To have the values in training-lab-account.yml
take precedence over those in the other files, give it as last parameter. To merge the sequence values in vpcs:
, use *d
to enable deep array merging. Resulting command:
yq eval-all 'select(fileIndex == 0) *d select(fileIndex == 1) *d select(fileIndex == 2)' account.yml network.yml training-lab-account.yml
Upvotes: 2