0

我刚开始学习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

我怎样才能做到这一点?

编辑:我需要将它保存在不同的变量中,以便我可以调用该变量...例如

if [[ $hd_AVG1 -eq 20 ]];
    then 
    do something...
elif [[ $hd_AVG2 -gt 40 ]];
    then
    do something...
fi
4

5 回答 5

6
$ awk '{print $1"="($2+$3+$4+$5)/4}' file
harddrive1=25
harddrive2=35
harddrive3=45
于 2012-10-17T16:07:10.990 回答
2

这个 bash 脚本应该做你想做的事。它要求bc进行浮点运算,因为 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]}
于 2012-10-17T16:14:11.527 回答
2

使用Perl(非常便携):

perl -lane 'print $F[0] . "=" . ($F[1] + $F[2] + $F[3] + $F[4]) / 4' file.txt
于 2012-10-17T16:49:51.750 回答
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
于 2012-10-18T15:54:18.387 回答
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/'

整个命令也包含在 中<( )并以 为来源.,即变量将在当前环境中可用。

于 2012-10-17T17:27:38.037 回答