如何在Bash脚本中使用sed将fonts.xml单行替换为另一文件存储的多行内容
适用于Android/Magisk环境的fonts.xml多行替换方案
你之前写的sed命令不生效主要有两个原因:一是Android系统自带的sed为toybox实现,和桌面端常用的GNU sed语法存在细微差异;二是直接在sed命令中嵌入多行xml内容需要处理大量转义字符(换行、&、尖括号、引号等),容错率极低。推荐直接读取外部存储的待替换内容文件实现需求,无需额外转义,兼容性更好。
可用实现方案
假设参数如下,你可以根据自己的实际路径调整:
- 待修改的目标文件:
fonts.xml - 存储自定义多行内容的文件:
custom_fonts.xml - 待匹配替换的目标行:
<family name="sans-serif">
方案1:sed实现(推荐,toybox sed兼容)
sed -i '/<family name="sans-serif">/{r custom_fonts.xml' -e 'd}' fonts.xml
命令逻辑:匹配到目标行后,先读取custom_fonts.xml的全部内容输出到当前位置,再删除原本的目标行,等同于完成替换。这里拆分-e参数是为了适配toybox sed的语法要求,避免把后续的删除指令识别为文件名的一部分。
方案2:awk实现(兼容性更强,全Android版本可用)
awk '/<family name="sans-serif">/{system("cat custom_fonts.xml");next}1' fonts.xml > temp_fonts.xml && mv temp_fonts.xml fonts.xml
Magisk模块适配注意事项
- 脚本中引用自定义文件时请使用Magisk提供的
$MODDIR变量指代当前模块目录,比如自定义文件放在模块根目录,路径写为$MODDIR/custom_fonts.xml - 修改完成后的
fonts.xml需要设置和系统原文件一致的权限,避免系统读取失败:chmod 644 fonts.xml chown root:root fonts.xml - 你要替换的内容已经完整定义了sans-serif字体族的字重配置,系统原本的Roboto字体本身就在全局fallback列表中,无需额外修改即可自动作为兜底字体使用。
内容的提问来源于stack exchange,提问作者Mistu Marsh
相关产品推荐
相关产品推荐

