如何使用bash显示我的标准差输出?

时间:2014-01-06 07:45:31

标签: bash shell standard-deviation

这是表格输出

    Month     CBS      GFS      HR   HR    Payroll   INCV
              cbs1      gfs1    hr1  hr2    hrm      incv1

    Standard
    Deviation  33.00   48.124  29.845 67.934 23.680 12.230
    (6Mths)
    2013-07     97      89      14    28    30        4
    2013-08     58     103      18    6     24        18
    2013-09     54     110      11    14    25        17
    2013-10     108    129      17    8     23        18
    2013-11     52     137      12    8     21        30
    2013-12     18     84       6     0     13        13
    2014-01     8      6        1     0     9         3

以下是我的bash脚本: 现在,标准偏差输出与表中显示的不同。需要帮助。

    #!/bin/bash


    for hostip in `cat $CONFIG `
    do

      name=`echo $hostip|cut -d\: -f1`
      ip=`echo $hostip|cut -d\: -f2`
      HTML=/tmp/test.html
      rm -f $HTML
      touch $HTML

      echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"/soc/stylesheet.css\" />" >> $HTML
       echo "<h2><b>Servers</b></h2>" >> $HTML
       echo "<table border="1">" >> $HTML
       echo "<tr><th rowspan="2">Month</th><th>CBS</th><th>GFS</th><th colspan="2">HR</th><th>Payroll</th><th>INCV</th></tr>" >> $HTML
       echo "<tr><th>cbs1</th><th>gfs1</th><th>hr1</th><th>hr1</th><th>hrm</th><th>incv1</th></tr>" >> $HTML
    for count in 6 5 4 3 2 1 0
    do
        MONTH=`date -d"$count month ago" +"%Y-%m"`
        CBS=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.22.41 |sort|uniq | wc -l`
        GFS=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.22.31 |sort|uniq | wc -l`
        HR1=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.10.1 |sort|uniq | wc -l`
        HR2=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.21.12 |sort|uniq | wc -l`
        PAYROLL=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.21.18 |sort|uniq | wc -l`
        INCV=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.22.71 |sort|uniq | wc -l`
        echo " <tr><th><a href=/soc/test/archive/tmp/tripwire.$MONTH.html>$MONTH</a><td>$CBS<td>$GFS<td>$HR1<td>$HR2<td>$PAYROLL<td>$INCV</tr>" >>$HTML
    done

    echo "</table>" >> $HTML

这是我的标准偏差计算

    count=0         # Number of data points; global.
    SC=3            # Scale to be used by bc. three decimal places.
    E_DATAFILE=90   # Data file error.

# ----------------- Set data file ---------------------
    if [ ! -z "$1" ]  # Specify filename as cmd-line arg?
    then
      datafile="$1" #  ASCII text file,
    else            #+ one (numerical) data point per line!
      datafile=/home/secmgr/attmrms1/data_tripwire1.sh
    fi              #  See example data file, below.

    if [ ! -e "$datafile" ]
    then
      echo "\""$datafile"\" does not exist!"
      exit $E_DATAFILE
    fi

计算平均值

    arith_mean ()
    {
      local rt=0         # Running total.
      local am=0         # Arithmetic mean.
      local ct=0         # Number of data points.

      while read value   # Read one data point at a time.
      do
        rt=$(echo "scale=$SC; $rt + $value" | bc)
        (( ct++ ))
      done

      am=$(echo "scale=$SC; $rt / $ct" | bc)

      echo $am; return $ct   # This function "returns" TWO values!
      #  Caution: This little trick will not work if $ct > 255!
      #  To handle a larger number of data points,
      #+ simply comment out the "return $ct" above.
    } <"$datafile"   # Feed in data file.

    sd ()
    {
      mean1=$1  # Arithmetic mean (passed to function).
      n=$2      # How many data points.
      sum2=0    # Sum of squared differences ("variance").
      avg2=0    # Average of $sum2.

    sdev=0    # Standard Deviation.

      while read value   # Read one line at a time.
      do
        diff=$(echo "scale=$SC; $mean1 - $value" | bc)
        # Difference between arith. mean and data point.
        dif2=$(echo "scale=$SC; $diff * $diff" | bc) # Squared.
        sum2=$(echo "scale=$SC; $sum2 + $dif2" | bc) # Sum of squares.
      done

        avg2=$(echo "scale=$SC; $sum2 / $n" | bc)  # Avg. of sum of squares.
        sdev=$(echo "scale=$SC; sqrt($avg2)" | bc) # Square root =
        echo $sdev                                 # Standard Deviation.

    } <"$datafile"   # Rewinds data file.

显示输出

    mean=$(arith_mean); count=$?   # Two returns from function!
    std_dev=$(sd $mean $count)

    echo
    #echo "<tr><td>"Number of data points in \""$datafile"\" = $count"<td>$mean<td>$std_dev</tr>" >> $HTML
    #echo "Arithmetic mean (average) = $mean"
    #echo "<tr><td>$std_dev</tr>" >> $HTML
    echo

我只想让标准偏差输出显示在表格中。

1 个答案:

答案 0 :(得分:0)

对于第一个bash脚本,可以改进此部分。 (需要GNU awk)

原始文件,需要多次读取日志文件。

for count in 6 5 4 3 2 1 0
    do
        MONTH=`date -d"$count month ago" +"%Y-%m"`
        CBS=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.22.41 |sort|uniq | wc -l`
        GFS=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.22.31 |sort|uniq | wc -l`
        HR1=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.10.1 |sort|uniq | wc -l`
        HR2=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.21.12 |sort|uniq | wc -l`
        PAYROLL=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.21.18 |sort|uniq | wc -l`
        INCV=`bzcat $LOG/$MONTH*.log.bz2|grep 10.55.22.71 |sort|uniq | wc -l`
        echo " <tr><th><a href=/soc/test/archive/tmp/tripwire.$MONTH.html>$MONTH</a><td>$CBS<td>$GFS<td>$HR1<td>$HR2<td>$PAYROLL<td>$INCV</tr>" >>$HTML
    done

更新到

for count in {6..0}
do
    MONTH=`date -d"$count month ago" +"%Y-%m"`
    bzcat $LOG/$MONTH*.log.bz2 |awk -v mon=$MONTH '/10.55.22.41/{CBS[$0]}
    /10.55.22.31/{GFS[$0]}
    /10.55.10.1/{HR1[$0]}
    /10.55.21.12/{HR2[$0]}
    /10.55.21.18/{PAYROLL[$0]}
    /10.55.22.71/{INCV[$0]}
    END{printf "<tr><th><a href=/soc/test/archive/tmp/tripwire.%s.html>%s</a><td>%s<td>%s<td>%s<td>%s<td>%s<td>%s</tr>",mon, mon, length(CBS), length(GFS), length(HR1), length(HR2), length(PAYROLL), length(INCV)}' >>$HTML
done

阅读其余代码。请告诉我你有什么问题?