bashshell的数组算法
我有许多(nTotal)个文件,每个文件都有一列长度L的浮点数,我想在所有这些文件的第I行和末尾添加条目。计算其平均值和标准偏差。 我首先阅读每个文件。然后我尝试将这个数组添加到数组中,这会给我一个语法错误:(标准)2:syntax error。我希望suma[I]现在包含所有文件第I行上所有条目的总和。然后我找到了平均值 编辑我根据建议更改了循环bashshell的数组算法,bash,arithmetic-expressions,data-files,Bash,Arithmetic Expressions,Data Files,我有许多(nTotal)个文件,每个文件都有一列长度L的浮点数,我想在所有这些文件的第I行和末尾添加条目。计算其平均值和标准偏差。 我首先阅读每个文件。然后我尝试将这个数组添加到数组中,这会给我一个语法错误:(标准)2:syntax error。我希望suma[I]现在包含所有文件第I行上所有条目的总和。然后我找到了平均值 编辑我根据建议更改了循环 for (( n= 1 ; n < $nTotal; n++ )) do IFS=$'\n' arr1=($(./a.out f
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
((n=1;n<$nTotal;n++)的
做
IFS=$'\n'
arr1=($(./a.out文件名| sed's/:.*/'))
对于((i=1;i<$L;i++)
做
sum[i]=`echo“${sum[i]}-${arr1[i]}”| bc`
完成
完成
对于((i=1;i<$L;i++)
做
ya=$(回音-1*${sum[i]}|bc)
aveSum=$(echo$ya/$nTotal | bc-l)
完成
Edit:/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
((i=1;i<$L;i++)的
做
ya=$(回音-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`
完成
在这里,对于val[I]元素,我得到了零,我不知道哪里出了问题。如果您能指导我解决这个问题,我将不胜感激。对于这个问题,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 ...
数学是直接从知名人士那里得到的。程序假设所有文件都有L
行,但如果少数文件有更多或更少的行,丢失的数据将被忽略;你可能想做一个更好的有效性测试。在只有一个文件有太多行的特定情况下,标准偏差计算将捕获一个除以零的值;在一次读取中,这并不重要,因为正确的数据已经打印出来了,但您可能也想修复它
该程序利用了两个awk特性:首先,数组被自动(并且延迟)初始化为0(如果用作数字);其次,
FNR
是当前文件中的行号。(NR
是整个输入中的行号,但在本例中,FNR
更有用。)对于((i=1;i…顺便说一句,我还建议使用set-x
查看脚本在运行时实际调用的内容(可以使用“PS4=”:$LINENO+”
显示它在任何给定时间的哪一行),找到它意外行为的第一个地方,并提出一个专门针对该行为的问题(如果不明显).大括号扩展不会创建算术环境,因此即使可以在大括号中使用参数扩展,也必须编写{1..$L}
,而不是{1..L}
。如果您现在还没有弄明白这一点,那么这个脚本会有很多严重的问题,其数量和严重程度足以使任何一个答案实际上都不可能对您有所帮助,除非您只是简单地重新编写脚本。也许您应该收回这个问题。请仔细阅读您提出的一些建议(特别是@CharlesDuffy提供的set-x
建议)尽可能地修复错误,然后返回一个更好的脚本和一个更集中的问题。谢谢。这非常好。我最终使用了c代码,但我仍然很好奇在shell中如何解决这个问题。谢谢:)