如何编写Bash脚本实现语义版本号的提取、更新与替换?
问题描述
我正在自动化发布包的创建工作,刚接触Bash脚本编写。有一个文件(比如version.h)包含以下版本定义:
#define VER_MAJOR 1 #define VER_MINOR 8 #define VER_BUILD 5
需要编写脚本完成:从文件中提取VER_MAJOR、VER_MINOR、VER_BUILD三个值,递增VER_BUILD后,将新版本号写回文件对应行。
目前已经能通过命令行用grep获取对应行和行号:
$ grep -n "#define VER_" version.h 98:#define VER_MAJOR 1 99:#define VER_MINOR 8 100:#define VER_BUILD 5
但不知道如何在脚本里解析这些结果、存储行号和版本号,再替换回文件。
解决方案
1. 提取版本号
直接用grep结合awk解析文件,提取三个版本字段的值,不需要单独处理行号(匹配关键字比依赖行号更稳定,避免文件行变动导致错误):
# 定义版本文件路径 VERSION_FILE="version.h" # 从文件中提取三个版本值 VER_MAJOR=$(grep "#define VER_MAJOR" $VERSION_FILE | awk '{print $3}') VER_MINOR=$(grep "#define VER_MINOR" $VERSION_FILE | awk '{print $3}') VER_BUILD=$(grep "#define VER_BUILD" $VERSION_FILE | awk '{print $3}')
2. 递增BUILD版本号
用Bash算术运算直接递增:
VER_BUILD=$((VER_BUILD + 1))
3. 将新版本号写回文件
用sed命令匹配VER_BUILD的定义行,替换数值:
# 替换VER_BUILD行的数值,-i.bak会生成备份文件(如version.h.bak) sed -i.bak "s/#define VER_BUILD\s*.*/#define VER_BUILD $VER_BUILD/" $VERSION_FILE # 可选:如果不需要备份文件,可删除 # rm $VERSION_FILE.bak
- 正则里的
\s*用来匹配任意数量的空格,适配文件里的格式差异;如果格式固定,也可以直接写对应数量的空格。
整合后的完整脚本
#Release Creation Script # 定义版本文件路径 VERSION_FILE="version.h" # Retrieve Current Version VER_MAJOR=$(grep "#define VER_MAJOR" $VERSION_FILE | awk '{print $3}') VER_MINOR=$(grep "#define VER_MINOR" $VERSION_FILE | awk '{print $3}') VER_BUILD=$(grep "#define VER_BUILD" $VERSION_FILE | awk '{print $3}') # Increment Build Number VER_BUILD=$((VER_BUILD + 1)) # Write Updated Version Back to file sed -i.bak "s/#define VER_BUILD\s*.*/#define VER_BUILD $VER_BUILD/" $VERSION_FILE # rm $VERSION_FILE.bak # 可选删除备份 # Create Git Tag git tag v${VER_MAJOR}.${VER_MINOR}.${VER_BUILD} # Get Current Git Information BUILD_TIME=$(date +%FT%T%z) GIT_REVISION=$(git rev-parse --short HEAD) GIT_BRANCH=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD) GIT_DIRTY=$(git diff-index --quiet HEAD -- || echo "✗-") GIT_TAG_DIRTY=$(git describe --exact-match --tags > /dev/null 2> /dev/null || echo "+") GIT_TAG=$(git describe --abbrev=0 --tags) # Concatenate Git info and Echo GITINFO=" buildTime = \"${BUILD_TIME}\" gitRevision = \"${GIT_DIRTY}${GIT_REVISION}${GIT_TAG_DIRTY}\" gitBranch = \"${GIT_BRANCH}\" gitTag = \"${GIT_TAG}\"" echo "$GITINFO" # Create Backup Package of Release git archive -o ${GIT_TAG}.zip master
注:原脚本里的$(git tag ...)、$(git archive ...)不需要用子shell执行,直接调用命令即可。
内容的提问来源于stack exchange,提问作者Jab00p
相关产品推荐
相关产品推荐

