【问题标题】:nested for loop not iterating the way I expect嵌套的 for 循环没有按照我期望的方式迭代
【发布时间】:2014-07-18 18:05:34
【问题描述】:

我有一个脚本,它从输入文件中获取最后一行,并迭代地将定义的“步骤”值添加到该行中的某些数据字段。外部循环将“step”添加到第一个数据字段,嵌套的内部循环将“step”添加到第二个数据字段。然后,旧数据字段值被新值替换,新行回显到我的命令行上(仅用于本论坛的目的)。最后,我将旧输入文件中的数据复制到一个新文件中,删除最后一行,并追加新的最后一行。

#!/bin/bash

step=0.1
inputfile=$1
limit_i=2
limit_j=2

lastline=$(awk END{print}<$inputfile)
x0=$(echo "$lastline" | awk '{print $1}')
y0=$(echo "$lastline" | awk '{print $2}')
for (( i=0; i <= $limit_i; i++))
do
   istep=$(echo "$i*$step" | bc)
   xnew=$(echo "$x0 $istep" | awk '{printf "%.16f", $1+$2}')
   lastline_new_x=${lastline/$x0/$xnew}
   for (( j=0; j <= $limit_j; j++))
   do
      jstep=$(echo "$j*$step" | bc)
      ynew=$(echo "$y0 $jstep" | awk '{printf "%.16f", $1+$2}')
      lastline_new_xy=${lastline_new_x/$y0/$ynew}
      echo "$lastline_new_xy"
   done
done

以下是我希望从该脚本获得的输出:

  0.0000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.0000000000000000  0.1000000000000000  1.2000000000000000   T   T   T
  0.0000000000000000  0.2000000000000000  1.2000000000000000   T   T   T
  0.1000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.1000000000000000  0.1000000000000000  1.2000000000000000   T   T   T
  0.1000000000000000  0.2000000000000000  1.2000000000000000   T   T   T
  0.2000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.2000000000000000  0.1000000000000000  1.2000000000000000   T   T   T
  0.2000000000000000  0.2000000000000000  1.2000000000000000   T   T   T

然而,实际的输出是:

  0.0000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.1000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.2000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.1000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.1000000000000000  0.1000000000000000  1.2000000000000000   T   T   T
  0.1000000000000000  0.2000000000000000  1.2000000000000000   T   T   T
  0.2000000000000000  0.0000000000000000  1.2000000000000000   T   T   T
  0.2000000000000000  0.1000000000000000  1.2000000000000000   T   T   T
  0.2000000000000000  0.2000000000000000  1.2000000000000000   T   T   T

第 4 - 9 行对我来说看起来不错。第 1 行在技术上看起来也不错,但我相信影响 2 和 3 的同样问题也会影响它。似乎出于某种原因,对于它的第一次通过,外部循环没有保持其值并允许内部循环完全通过,而是迭代并保持内部循环值。我做了很多谷歌搜索并与一些人交谈过,但无法弄清楚错误是什么。我已经在这个问题上停留了一段时间,对于解决方案的任何建议将不胜感激。

【问题讨论】:

  • 有趣的代码,但请在awk 中一并完成。所有Var=$(...| ...) 都很贵。祝你好运。
  • 至少,使用参数扩展和/或read 来提取部分值,而不是通过管道传递到awk
  • 0.1 不能用默认的浮点表示准确表示,所以你会得到各种各样的舍入错误。试试这个:awk 'BEGIN {printf "%.20f", 0.1}'——如果可能的话,重新设计你的算法以增加一个整数,然后除以 10 来表示。
  • 谢谢大家的cmets。这是我的第一个脚本,所以我仍在学习并感谢有机会进行改进。我会尝试这些建议!

标签: bash for-loop


【解决方案1】:

第二个输出行的错误(与第三个类似......)是与

      lastline_new_xy=${lastline_new_x/$y0/$ynew}

您想用ynew (0.1000000000000000) 替换第二个数据字段(y0,即0.0000000000000000),但由于第一个数据字段也是0.0000000000000000${parameter/pattern/string} 模式替换只替换第一个匹配,你得到

  0.1000000000000000  0.0000000000000000  1.2000000000000000   T   T   T

而不是

  0.0000000000000000  0.1000000000000000  1.2000000000000000   T   T   T

有无数种方法可以解决这个问题,但最快的方法可能是将上面的脚本行更改为

      lastline_new_xy=${lastline_new_x/$xnew  $y0/$xnew  $ynew}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    相关资源
    最近更新 更多