如何在Bash循环中将浮点数转换为整数适配HPC目录?
问题描述
我用Bash循环从HPC递归复制2个文件到本地,需要遍历所有处理器和时间步。HPC上的时间步目录是整数形式(如1、2、3),但我用seq 0 0.5 10生成步长时,循环变量$j会被解析为浮点数(如1.0、2.0),导致scp报错找不到对应目录(正确路径应为/scratch/Run1/processor0/1这类)。请问如何在脚本中将$j转为无小数的整数?
使用的脚本
for i in $(seq 0 1 23) do mkdir Run1/processor$i for j in $(seq 0 0.5 10); do mkdir Run1/processor$i/$j scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j/p Run1/processor$i/$j/ scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j/U Run1/processor$i/$j/ done done
报错信息
scp: /scratch/Run1/processor0/1.0/p: No such file or directory
解决方法
这里提供几种在Bash中将浮点数$j转为整数的方案,任选其一即可:
1. 使用Bash参数扩展移除小数部分
直接通过字符串处理去掉.0后缀,适合你的场景(所有j均为.0结尾的浮点数):
for i in $(seq 0 1 23) do mkdir -p Run1/processor$i for j in $(seq 0 0.5 10); do # 移除小数部分,得到整数 j_int=${j%.*} mkdir -p Run1/processor$i/$j_int scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j_int/p Run1/processor$i/$j_int/ scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j_int/U Run1/processor$i/$j_int/ done done
注:给mkdir加上-p参数,可避免目录已存在时的报错。
2. 使用printf格式化输出整数
利用printf的格式化功能将浮点数转为整数,通用性更强,哪怕遇到非.0结尾的浮点数也能自动四舍五入:
for i in $(seq 0 1 23) do mkdir -p Run1/processor$i for j in $(seq 0 0.5 10); do j_int=$(printf "%.0f" "$j") mkdir -p Run1/processor$i/$j_int scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j_int/p Run1/processor$i/$j_int/ scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j_int/U Run1/processor$i/$j_int/ done done
3. 修改seq的输出格式(仅适用于GNU seq)
如果你的系统是GNU环境,可以直接让seq输出整数格式,省去后续转换步骤:
for i in $(seq 0 1 23) do mkdir -p Run1/processor$i # 使用-f参数指定输出格式为整数,自动去掉末尾的.0 for j in $(seq -f "%g" 0 0.5 10); do mkdir -p Run1/processor$i/$j scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j/p Run1/processor$i/$j/ scp -r xx@login.hpc.xx.xx:/scratch/Run1/processor$i/$j/U Run1/processor$i/$j/ done done
内容的提问来源于stack exchange,提问作者rk1
相关产品推荐
相关产品推荐

