Perl正则替换YAML文件版本号未达预期问题求助
Hey Stefan, let's walk through why your current regex and Perl command aren't working, and get that version number updated correctly.
What's Going Wrong?
You've hit two key issues with your approach:
Shell variables aren't being passed to Perl
When you wrap your Perl script in single quotes ('s/$search/$replace/m'), the shell doesn't expand the$searchand$replacevariables—Perl sees literal$searchand$replaceinstead of their values. Since those variables aren't defined in Perl, your regex never matches anything.Your replacement breaks YAML structure
Your regexversion:\s*([^\s]+)matches the entire stringversion: 1.2. If it did work, replacing that with just1.3would turn the line into1.3, losing theversion:key entirely—definitely not what you want for a valid YAML file.
Working Solutions
Here are two solid ways to fix this:
Option 1: Hardcode the pattern directly in Perl (simplest & most reliable)
Use a capture group to preserve the version: part, then replace just the version number:
perl -pie 's/(version:\s*)\S+/\11.3/' ./test.yml
(version:\s*)captures the key and any following whitespace\S+matches the existing version number (all non-whitespace characters)\11.3inserts the captured key/whitespace followed by your new version
Option 2: Use shell variables with proper escaping
If you want to keep using variables for flexibility, wrap your Perl script in double quotes so the shell expands the variables. Just remember to escape backslashes so Perl sees them correctly:
SEARCH_PATTERN="(version:\\s*)\\S+" NEW_VERSION="\\11.3" perl -pie "s/$SEARCH_PATTERN/$NEW_VERSION/" ./test.yml
- We escape
\as\\because double quotes let the shell parse escape characters \1becomes\\1to prevent the shell from treating it as a special sequence
Result
After running either command, your test.yml will look exactly like you want:
app: version: 1.3 name: abc
内容的提问来源于stack exchange,提问作者Stefan

