如何编写Shell脚本批量将分子坐标替换到计算模板文件
解决多行坐标替换模板的zsh脚本方案
核心思路
既然已经拆分好每组坐标到单独文件,核心是用坐标文件的多行内容替换模板中COORDINATES标记行,同时替换CONF_NUMBER为对应序号。下面提供两种实用的zsh脚本实现方式:
方法一:使用sed(简洁高效)
sed的r命令可以读取外部文件内容插入到指定位置,结合替换命令完成需求:
#!/usr/bin/zsh # 定义模板文件路径 TEMPLATE="./template.in" # 按数值顺序遍历所有坐标文件(避免conf_10排在conf_2前) for coord_file in $(ls -v conf_*.coord); do # 从文件名提取构型序号(假设文件名为conf_1.coord格式) conf_num=$(echo "$coord_file" | sed 's/conf_\([0-9]*\).coord/\1/') # 定义输出文件名 output_file="input_${conf_num}.in" # 执行双替换:先替换序号,再用坐标文件替换COORDINATES行 sed -e "s/CONF_NUMBER/${conf_num}/" \ -e "/COORDINATES/{r ${coord_file}" \ -e "d}" \ "$TEMPLATE" > "$output_file" echo "已生成:$output_file" done
关键逻辑解释:
ls -v:按文件名中的数字大小排序,确保构型序号顺序正确/COORDINATES/{r ${coord_file}; d}:匹配到COORDINATES所在行时,先读取坐标文件内容插入到该行下方,再删除原标记行,实现多行替换- 双
-e选项:依次执行序号替换和坐标替换两个操作
方法二:使用awk(灵活可控)
如果需要更复杂的逻辑处理,awk的文件读取功能更灵活:
#!/usr/bin/zsh TEMPLATE="./template.in" for coord_file in $(ls -v conf_*.coord); do # 用awk分割文件名提取序号 conf_num=$(echo "$coord_file" | awk -F '[_.]' '{print $2}') output_file="input_${conf_num}.in" awk -v conf="$conf_num" -v coord_path="$coord_file" ' { # 替换序号标记 if ($0 ~ /CONF_NUMBER/) { gsub(/CONF_NUMBER/, conf) print $0 } # 替换坐标标记:读取坐标文件所有行输出 else if ($0 ~ /COORDINATES/) { while ((getline coord_line < coord_path) > 0) { print coord_line } close(coord_path) } # 其他行直接输出 else { print $0 } }' "$TEMPLATE" > "$output_file" echo "已生成:$output_file" done
关键逻辑解释:
-v选项:将shell变量传递给awk内部使用getline循环:逐行读取坐标文件内容并输出,替换原COORDINATES标记行close(coord_path):避免打开过多文件句柄
注意事项
- 确保模板中的
COORDINATES是单独一行,避免匹配不完整 - 如果坐标文件路径包含空格,需将变量用双引号括起来(如
"${coord_file}") - 若序号不是连续数字,
ls -v依然能保证按数值排序,比默认字典序更可靠
内容的提问来源于stack exchange,提问作者isolated matrix
相关产品推荐
相关产品推荐

