如何通过循环迭代修改脚本中的nvt_xx.inp输入文件名?
解决方案
根据你的需求,这里提供几种实用的方法来迭代修改脚本中的文件名数字:
1. 批量生成不同数字版本的脚本文件
如果你需要为每个数字(10、20、30…)生成独立的脚本,可以用shell循环配合sed实现:
# 假设原始脚本名为 run_cp2k.sh,生成10到100、步长10的版本 for num in {10..100..10}; do # 替换脚本中的输入输出文件名 sed "s/nvt_10\.inp/nvt_${num}\.inp/g; s/nvt_10\.out/nvt_${num}\.out/g" run_cp2k.sh > run_cp2k_${num}.sh # 赋予执行权限 chmod +x run_cp2k_${num}.sh done
{10..100..10}是Bash的序列语法,生成10、20…100的数字序列sed的替换规则同时修改.inp和.out文件名,确保输入输出对应
2. 在单个脚本内循环执行所有任务
如果不想生成多个脚本,直接在原脚本中加入循环,一次性处理所有数字任务:
修改后的脚本内容:
### beginning of executable commands ### load the necessary module files module load GCC/11.3.0 OpenMPI/4.1.4 CP2K/9.1 ### your program goes here (loop over target numbers) for num in {10..100..10}; do $MPIEXEC $FLAGS_MPI_BATCH cp2k.popt -i nvt_${num}.inp -o nvt_${num}.out done
运行这个脚本时,会依次执行nvt_10、nvt_20…对应的CP2K任务。
3. 用awk实现文件名替换(解决你之前的失败问题)
如果坚持使用awk,你可能之前的写法存在正则匹配或变量传递问题,以下是正确的实现:
单个数字替换(比如把10改成20)
awk '{gsub(/nvt_10\.inp/, "nvt_20.inp"); gsub(/nvt_10\.out/, "nvt_20.out")}1' run_cp2k.sh > run_cp2k_20.sh
批量生成不同版本
结合shell循环,用-v选项传递数字变量给awk:
for num in {20..100..10}; do awk -v new_num="$num" '{ gsub(/nvt_[0-9]+\.inp/, "nvt_"new_num".inp"); gsub(/nvt_[0-9]+\.out/, "nvt_"new_num".out") }1' run_cp2k.sh > run_cp2k_${num}.sh done
nvt_[0-9]+\.inp是正则表达式,匹配任意数字的输入文件名-v new_num="$num"把shell循环的数字传递给awk,实现动态替换
4. 原地修改原脚本文件
如果需要直接修改原脚本(比如把10改成20),可以用sed的原地替换功能:
# GNU sed(Linux) sed -i 's/nvt_10\.inp/nvt_20.inp/g; s/nvt_10\.out/nvt_20.out/g' run_cp2k.sh # BSD sed(macOS),会生成备份文件 run_cp2k.sh.bak sed -i.bak 's/nvt_10\.inp/nvt_20.inp/g; s/nvt_10\.out/nvt_20.out/g' run_cp2k.sh
内容的提问来源于stack exchange,提问作者Chintu
相关产品推荐
相关产品推荐

