【问题标题】:Array arithmetic bash shell数组算术 bash shell
【发布时间】:2014-12-24 01:22:34
【问题描述】:

我有许多(nTotal)个文件,每个文件都有一列长度为L的浮点数,我想在所有这些文件的第 i_th 行添加条目和在末尾。计算其平均值和标准差。 我首先阅读每个文件。然后我尝试将此数组添加到一个数组中,这给了我一个语法错误:(standard_in) 2: syntax error。我希望 suma[i] 现在包含所有文件的第 i_th 行上所有条目的总和。然后我找到平均值 编辑我按照建议更改了 for 循环。

for (( n= 1 ; n < $nTotal; n++ ))
do

   IFS=$'\n'
   arr1=($(./a.out filename | sed 's/:.*//'))

   for (( i= 1 ; i < $L; i++ ))       
   do
       sum[i]=`echo "${sum[i]} - ${arr1[i]}" | bc`
   done
done

for (( i= 1 ; i < $L; i++ ))  
do
   ya=$(echo -1*${sum[i]} | bc)
   aveSum=$(echo $ya/$nTotal | bc -l)
done

编辑: ./a.out 生成具有一列浮点数的文件。

为了找到标准偏差,我再次读取数据文件并将它们存储在数组中(我确信这不是最聪明的方法,但我想不出其他任何方法。 )。我也找不到标准差:

for (( i= 1 ; i < $L; i++ ))  
 do
    ya=$(echo -1*${sum[i]} | bc)
    ta=$(echo $ya/$nTotal | bc -l)

    tempval=`echo "${arr1[i]} - $ta * ${arr1[i]} - $ta" | bc`
    val[i]=`echo "${val[i]} - $tempval" | bc`
 done

这里 val[i] 元素的值为零,我不知道出了什么问题。如果您能指导我解决这个问题,我将不胜感激。

【问题讨论】:

  • for ((i=1; i&lt;=L; i++)); do ...; done 是写出for i in {1..L} 的意思的正确方式。
  • ...顺便说一下,这是mywiki.wooledge.org/BashPitfalls中的第33条
  • 我还建议使用 set -x 查看脚本在运行时实际调用的内容(可能使用 PS4=':$LINENO+' 显示它在任何给定时间所在的行),找到第一个位置它的行为出乎意料,并提出了一个专门针对该行为的问题(如果不明显)。
  • 大括号扩展不会创建算术环境,因此即使参数扩展可以用在大括号中,您仍然需要编写{1..$L},而不是{1..L}
  • 如果您现在还没有弄清楚这一点,那么您的这个脚本有许多 严重 问题,其数量和严重性足以让任何人几乎不可能回答实际上对您有所帮助,而不是简单地为您重写脚本。也许你应该收回这个问题。回顾您收到的一些建议(尤其是来自@CharlesDuffy 的set -x 建议),尽可能地修复错误,然后提供更好的脚本和更有针对性的问题。

标签: bash arithmetic-expressions data-files


【解决方案1】:

对于这个问题,Bash 可能并不是最简单的,特别是因为它没有实现非整数运算。我会使用 awk:

awk '{ n[FNR]++;
       delta = $1 - mean[FNR];
       mean[FNR] += delta / n[FNR];
       m2[FNR] += delta * ($1 - mean[FNR]);
     }
     END {for (i=1; i in n; ++i)
            print mean[i], sqrt(m2[i]/(n[i]-1));
     }' file1 file2 ...

数学直接取自著名的"online" mean and variance algorithms。该程序假定所有文件都具有确切的L 行,但如果少数文件或多或少,则将忽略丢失的数据;你可能想做一个更好的有效性测试。在只有一个文件有太多行的特殊情况下,标准差计算将捕获除以零;在一次阅读中,这并不重要,因为已经打印了正确的数据,但您可能也想修复它。

该程序利用了几个 awk 特性:首先,数组被自动(并且延迟地)初始化为 0(如果用作数字);其次,FNR 是当前文件中的行号。 (NR 是整个输入中的行号,但在这种情况下FNR 更有用。)

【讨论】:

  • 谢谢。这是非常好的。我最终使用了一个 c 代码,但是我仍然很好奇在 shell 中解决这个问题的方法是什么。谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
  • 2015-06-02
  • 1970-01-01
  • 2015-10-21
  • 2011-03-02
  • 2012-04-22
  • 1970-01-01
相关资源
最近更新 更多