Bash将数组内容插入config.xml指定位置,避免追加到文件末尾
原脚本的核心缺陷
- 写入逻辑完全错位:使用
>>重定向追加内容时,默认是把内容写到目标文件的物理末尾,没有任何定位插入位置的逻辑,是内容跑到文件尾部的根本原因 - 变量名不匹配:脚本中定义的配置路径变量为
USER_CONF,实际写入时却引用了未定义的EXTERNAL_USER_CONF,路径指向存在逻辑错误 - 生成的XML格式错误:原printf语句输出的标签存在语法缺失,例如
<name><%s/name>斜杠和尖括号位置错误,会生成无效的XML节点;且标签名与预期输出的domain不匹配 - 无占位符替换逻辑:未针对配置文件中预留的
USER_TO_INSERT_HERE标记做对应处理,完全没有触达预期的插入位置
适配需求的实现方案
方案1:基于sed占位符替换(适配现有预留标记的场景)
提前遍历数组生成逐行排列的XML片段,通过sed命令匹配到USER_TO_INSERT_HERE标记所在行后,直接将该行替换为提前生成的多行内容,保证格式整齐、逐行排列:
#!/bin/bash NAME_ID=( User1 User2 User3 ) USER_CONF=/opt/test/config.xml # 初始化存储插入内容的变量,逐行添加换行符保证独立成行 insert_block="" for i in "${NAME_ID[@]}"; do # 匹配原文件的缩进层级,保证整体格式统一 insert_block+=" <domain><id>ID</id><name>${i}</name></domain>\n" done # 匹配到占位符行时执行整行替换,保留原文件其余结构不变 sed -i "/USER_TO_INSERT_HERE/c\\ ${insert_block}" "$USER_CONF"
方案2:逐行读入拼接(跨版本兼容场景)
如果担心不同环境下sed多行替换的兼容性问题,可以通过逐行读取原配置文件、遇到占位符行时批量插入生成内容的方式实现,逻辑更透明,无特殊语法依赖:
#!/bin/bash NAME_ID=( User1 User2 User3 ) USER_CONF=/opt/test/config.xml # 用数组存储每一行要插入的内容,保证每行独立排列 insert_lines=() for i in "${NAME_ID[@]}"; do insert_lines+=(" <domain><id>ID</id><name>${i}</name></domain>") done # 逐行读取原文件,临时写入拼接后的内容,最后替换原文件 while IFS= read -r line; do # 匹配到占位符行时,输出所有提前准备的插入内容 if [[ "$line" == *"USER_TO_INSERT_HERE"* ]]; then for line in "${insert_lines[@]}"; do echo "$line" done else # 其余行保持原内容不变 echo "$line" fi done < "$USER_CONF" > "${USER_CONF}.tmp" && mv "${USER_CONF}.tmp" "$USER_CONF"
两种方案执行后,都会在USER_TO_INSERT_HERE的位置逐行插入3条用户配置,最终生成的结构与预期完全一致,不会出现内容挤在同一行、或是追加到文件末尾的问题。
内容的提问来源于stack exchange,提问作者Rado Ratko
相关产品推荐
相关产品推荐

