使用yq v4修改YAML:避免&与*字符被自动添加引号
The issue you're facing is because your original command treats *My-Step as a string value, so yq automatically quotes it to ensure valid YAML syntax. However, since *My-Step is intended to be a YAML alias reference (not a literal string), we need to create an alias node instead of a string. Here's how to fix this with mikefarah/yq (the Go-based tool your syntax uses):
Solution 1: Use the alias() Function
This directly creates a YAML alias node, which will output as *My-Step without quotes:
yq eval '.pipelines.branches.develop = [{"step": alias("My-Step")}] + (.pipelines.branches.develop // [])' bitbucket-pipelines.yml
alias("My-Step")generates the alias reference*My-Step(matching the anchor&My-Stepdefined elsewhere in your YAML).(.pipelines.branches.develop // [])ensures we fall back to an empty array if thedevelopbranch pipeline doesn't exist yet.
Solution 2: Parse Raw YAML with load_str()
If you prefer writing the exact YAML snippet you want to add, use load_str() to parse it correctly:
yq eval '.pipelines.branches.develop = (load_str("- step: *My-Step") + (.pipelines.branches.develop // []))' bitbucket-pipelines.yml
This parses the raw YAML string into the proper node structure, preserving the alias without quotes.
Handling Anchors (&)
For characters like & (used for YAML anchors), apply the same logic. To add an anchor definition:
Using anchor() Function
yq eval '.definitions.steps += [{"step": anchor("My-Step", {"script": ["echo \"Hello World\""]})}]' bitbucket-pipelines.yml
Using load_str()
yq eval '.definitions.steps += load_str("- step: &My-Step\n script:\n - echo \"Hello World\"")' bitbucket-pipelines.yml
Both approaches will output the anchor &My-Step without quotes, as intended.
Key Takeaway
When working with YAML-specific syntax like aliases (*) and anchors (&), avoid treating them as string values. Use yq's built-in functions to create the appropriate node types, which ensures the output YAML is both valid and formatted as you expect.
内容的提问来源于stack exchange,提问作者Kelly

