Linux可用的sed -i修改JSON命令在macOS报错,求跨平台兼容方案
解决sed命令跨Linux与macOS兼容的问题
你遇到的问题其实是Linux上的GNU sed和macOS默认的BSD sed之间的语法差异导致的——两者在-i选项的处理以及部分命令格式上有明显区别。下面给你两种通用的解决方案,都能在两个系统的Shell脚本里正常运行:
方案1:适配-i选项并修正c命令写法
BSD sed要求-i参数必须指定备份后缀(哪怕你不需要生成备份文件,也得写成-i ''的形式),而GNU sed允许直接用-i不带后缀。另外,BSD sed的c\命令(整行替换)要求后面必须紧跟换行再写替换内容,我们可以通过以下写法兼容两者:
sed -i'' -e '/brand/c\ "brand": "valueModified"' ./config/brand.config.json
关键细节:
-i'':没有空格的写法同时兼容两个sed版本——GNU sed会忽略空后缀(等同于不备份),BSD sed则会理解为不生成备份文件-e:明确指定编辑命令,避免不同版本对命令内容的解析歧义c\后换行:BSD sed强制要求这个换行,而GNU sed也支持这种写法,所以用换行来统一格式
方案2:改用s替换命令(更灵活)
如果你的需求只是修改brand字段的取值,没必要用整行替换的c命令,用s(字符串替换)命令会更简洁,也更不容易出兼容问题:
sed -i'' -e 's/"brand": "[^"]*"/"brand": "valueModified"/' ./config/brand.config.json
说明:
- 这个命令会精准匹配
"brand": "xxx"格式的内容,把双引号里的旧值替换成valueModified,不需要担心整行格式的变动 - 同样用
-i''来适配两个平台的-i选项差异
小提示:用变量传递动态值
如果valueModified是动态的变量,记得调整引号转义,比如:
NEW_BRAND="MyCustomBrand" sed -i'' -e "s/\"brand\": \"[^\"]*\"/\"brand\": \"$NEW_BRAND\"/" ./config/brand.config.json
用双引号包裹sed命令,让Shell正确解析变量,同时转义JSON里的双引号避免语法错误。
内容的提问来源于stack exchange,提问作者FlorentGui




