如何用sed兼容GNU/非GNU环境替换文件首个version字段
跨环境替换npm配置文件首个version字段方案
兼容两种sed环境的实现
不同平台的sed语法存在两处核心差异:GNU sed独有0,/pattern/地址范围语法、-i参数的备份后缀要求不同,空模式匹配的写法跨环境会触发报错,可通过环境判断适配两种场景:
# 批量处理package.json和package-lock.json,自动跳过不存在的文件 for file in package.json package-lock.json; do [ -f "$file" ] || continue if sed --version 2>/dev/null | grep -q GNU; then # GNU sed 环境(Linux默认) sed -i "0,/^ *\"version\": *\"[^\"]*\",/s// \"version\": \"$NEW_VERSION\",/" "$file" else # 非GNU sed 环境(macOS默认) sed -i '' "1,/^ *\"version\": *\"[^\"]*\",/s/^ *\"version\": *\"[^\"]*\",/ \"version\": \"$NEW_VERSION\",/" "$file" fi done
全平台通用awk方案(无需环境判断)
如果不想做sed类型判断,可使用awk实现完全兼容,所有类Unix系统默认都支持awk:
for file in package.json package-lock.json; do [ -f "$file" ] || continue awk -v ver="$NEW_VERSION" '!flag && /^ *"version": *"[^"]*",/ { print " \"version\": \"" ver "\"," flag=1 next }1' "$file" > tmp && mv tmp "$file" done
说明
- 两种方案都会只替换文件中第一个匹配的version字段,后续出现的version(比如依赖包的version字段)不会被修改
- 内置了文件存在性判断,不需要同时存在两个配置文件也可以正常运行
内容的提问来源于stack exchange,提问作者BastienSander
相关产品推荐
相关产品推荐

