我刚开始学习shell脚本。
我正在尝试从结构如下的文件中读取:
harddrive1 10 20 30 40
harddrive2 20 30 40 50
harddrive3 30 40 50 60
我想以某种方式将每行的平均值保存在一个单独的变量中......只有3行,5列。 所以我的输出是:
hd_AVG1=20
hd_AVG2=35
hd_AVG3=45
我该如何实现?
编辑:我需要将它保存在DIFFERENT变量中,以便我可以调用变量...例如
if [[ $hd_AVG1 -eq 20 ]];
then
do something...
elif [[ $hd_AVG2 -gt 40 ]];
then
do something...
fi
答案 0 :(得分:6)
$ awk '{print $1"="($2+$3+$4+$5)/4}' file
harddrive1=25
harddrive2=35
harddrive3=45
答案 1 :(得分:2)
这个bash脚本应该做你想要的。它调用bc
来执行float算术,因为bash本身不能这样做。
#!/bin/bash
while read -a line ; do
sum=0
for ((i=1; i<${#line[@]}; i++)) ; do
let sum+=line[i]
done;
hd[j++]=$(bc -l <<< "$sum/($i-1)")
done < input
echo ${hd[0]} ${hd[1]} ${hd[2]}
答案 2 :(得分:2)
使用Perl
(非常便携):
perl -lane 'print $F[0] . "=" . ($F[1] + $F[2] + $F[3] + $F[4]) / 4' file.txt
答案 3 :(得分:2)
使用数组填充技巧我刚从@steve学习:
$ cat file
harddrive1 10 20 30 40
harddrive2 20 30 40 50
harddrive3 30 40 50 60
$
$ hd_AVG=($(awk '{print ($2+$3+$4+$5)/4}' file))
$ echo "${hd_AVG[0]}"
25
$ echo "${hd_AVG[1]}"
35
$ echo "${hd_AVG[2]}"
45
答案 4 :(得分:1)
你可以使用coreutils和sed:
这样做. <(paste -d= \
<(cut -d' ' -f1 infile ) \
<(cut -d' ' -f2- infile | sed 's/$/ + + + 4 \/ p/' | dc) \
)
echo $harddrive1 $harddrive2 $harddrive3
输出:
25 35 45
<( )
表示法运行命令并通过fifo管理其输出,因此paste
看到两个管道并将其输出列为=
作为分隔符。
第二个cut
获取文件中的数字,sed
将相应的运算符附加到数字上,然后让dc
进行计算。 dc
的输入如下所示:
cut -d' ' -f2- infile | sed 's/$/ + + + 4 \/ p/'
输出:
10 20 30 40 + + + 4 / p
20 30 40 50 + + + 4 / p
30 40 50 60 + + + 4 / p
dc
是反向抛光计算器;它支持任意精度,但需要告知使用小数。这将使dc
使用两位小数:
cut -d' ' -f2- dims | sed 's/^/2k/; s/$/ + + + 4 \/ p/'
整个命令也包含在<( )
中并且来源.
,即变量将在当前环境中可用。