0

我正在尝试设计一个 Unix shell 脚本(最好是通用 sh),它将获取一个内容为数字的文件,每行一个。这些数字是从 mpstat 获得的 CPU 空闲时间:

cat ${PARSE_FILE} | awk '{print $13}' | grep "^[!0-9]" > temp.txt

所以该文件是一个列表,如果数字,如:

46.19
93.41
73.60
99.40
95.80
96.00
77.10
99.20
52.76
81.18
69.38
89.80
97.00
97.40
76.18
97.10

这些值的真正含义是第 1 行用于核心 1,第 2 行用于核心 2,等等……对于 X 个核心(在我的情况下为 8) - 所以每第 9 行再次用于核心 1,等等……

原始文件如下所示:

10/28/2013  Linux 2.6.32-358.el6.x86_64 (host)  10/28/2013  _x86_64_    

(32 CPU)
10/28/2013  
10/28/2013  02:25:05 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
10/28/2013  02:25:15 PM    0   51.20    0.00    2.61    0.00    0.00    0.00    0.00    0.00   46.19
10/28/2013  02:25:15 PM    1    6.09    0.00    0.50    0.00    0.00    0.00    0.00    0.00   93.41
10/28/2013  02:25:15 PM    2   25.20    0.00    1.20    0.00    0.00    0.00    0.00    0.00   73.60
10/28/2013  02:25:15 PM    3    0.40    0.00    0.20    0.00    0.00    0.00    0.00    0.00   99.40
10/28/2013  02:25:15 PM    4    3.80    0.00    0.40    0.00    0.00    0.00    0.00    0.00   95.80
10/28/2013  02:25:15 PM    5    3.70    0.00    0.30    0.00    0.00    0.00    0.00    0.00   96.00
10/28/2013  02:25:15 PM    6   21.70    0.00    1.20    0.00    0.00    0.00    0.00    0.00   77.10
10/28/2013  02:25:15 PM    7    0.70    0.00    0.10    0.00    0.00    0.00    0.00    0.00   99.20
10/28/2013  02:25:25 PM    0   45.03    0.00    1.61    0.00    0.00    0.60    0.00    0.00   52.76
10/28/2013  02:25:25 PM    1   17.82    0.00    1.00    0.00    0.00    0.00    0.00    0.00   81.18
10/28/2013  02:25:25 PM    2   29.62    0.00    1.00    0.00    0.00    0.00    0.00    0.00   69.38
10/28/2013  02:25:25 PM    3    9.70    0.00    0.40    0.00    0.00    0.10    0.00    0.00   89.80
10/28/2013  02:25:25 PM    4    2.40    0.00    0.60    0.00    0.00    0.00    0.00    0.00   97.00
10/28/2013  02:25:25 PM    5    2.00    0.00    0.60    0.00    0.00    0.00    0.00    0.00   97.40
10/28/2013  02:25:25 PM    6   22.92    0.00    0.90    0.00    0.00    0.00    0.00    0.00   76.18
10/28/2013  02:25:25 PM    7    2.40    0.00    0.50    0.00    0.00    0.00    0.00    0.00   97.10

我正在尝试设计一个脚本,它将核心数量和这个文件作为一个变量,并让我得到每个核心的平均值,但我不知道该怎么做。这是我所拥有的:

cat ${PARSE_FILE} | awk '{print $13}' | grep "^[!0-9]" > temp.txt
NUMBER_OF_CORES=8
NUMBER_OF_LINES=`awk ' END { print NR } ' temp.txt`
NUMBER_OF_VALUES=`echo "scale=0;${NUMBER_OF_LINES}/${NUMBER_OF_CORES}" | bc`
for i in `seq 1 ${NUMBER_OF_CORES}`
do
  awk 'NR % $i == 0' temp.txt
  echo Core: ${i} Average: xx
done

所以我有每个核心具有的值(核心上的行)的数量,所以这是我需要跳过的每第 n 行,但我不知道如何干净地做到这一点。我基本上需要在文件中循环每个“NUMBER_OF_CORES”次,跳过每个“NUMBER_OF_CORES”行并将它们相加除以“NUMBER_OF_VALUES”。

4

4 回答 4

1

countCores.sh 下面的脚本基于您在 temp.txt 中提供的数据。这可能不是您想要的,但会给您一些想法。我不确定您想要的总体总平均值是多少,所以我只是选择在第一列中显示所有 8 个内核的平均值。我还使用 cat -n 来表示核心编号。希望这可以帮助。冯贝尔

#!/bin/bash
#Execute As: countCores.sh temp.txt 8
AllCoreTotals=0
DataFile="$1"
NumCores="$2"
AllCoreTotals=0
NumLines="`cat -n $DataFile|cut -f1|tail -1|tr -d " "`"
PrtCols="`echo $NumLines / $NumCores|bc`"
clear;echo;echo
echo "============================================================="
pr -t${PrtCols} $DataFile|tr -d "\t"|tr -s " "  "+"|bc |\
while read CoreTotal
    do
       CoreAverage=`echo $CoreTotal / $PrtCols|bc`
       echo "$CoreTotal     Core Average $CoreAverage"
       AllCoreTotals="`echo $CoreTotal + $AllCoreTotals|bc`"
       echo "$AllCoreTotals"  > AllCoreTot.tmp
    done|cat -n
AllCoreAverage=`cat AllCoreTot.tmp`
AllCoreAverage="`echo $AllCoreAverage / $NumCores|bc`"
echo "============================================================="
echo "(Col One) Total Core Average: $AllCoreAverage "
rm $DataFile
rm AllCoreTot.tmp
于 2013-10-29T03:31:39.810 回答
1

为什么不同时对所有内核执行此操作:

awk -f prog.awk ${PARSE_FILE}

然后prog.awk放入

    {   if ((NF == 13) && ($4 != "CPU"))
        {   SUM[$4] += $13;
            CNT[$4]++;
        }
    }
END {   for(loop in SUM)
        {   printf("CPU: %d  Total: %d  Count: %d  Average: %d\n",
                    loop, SUM[loop], CNT[loop], SUM[loop]/CNT[loop]);
        }
    }

如果你想在一行上做:

awk '{if ((NF == 13) && ($4 != "CPU")){SUM[$4] += $13;CNT[$4]++;}} END {for(loop in SUM){printf("CPU: %d  Total: %d  Count: %d  Average: %d\n", loop, SUM[loop], CNT[loop], SUM[loop]/CNT[loop]);}}'  ${PARSE_FILE}
于 2013-10-29T12:49:55.237 回答
1

这会吗?

awk '/CPU/&&/idle/{f=1;next}f{a[$4]+=$13;b[$4]++}END{for(i in a){print i,a[i]/b[i]}}' your_file

实际上这里不需要核心的数量。它将计算文件中所有可用内核的平均空闲时间

测试:

> cat temp
10/28/2013  Linux 2.6.32-358.el6.x86_64 (host)  10/28/2013  _x86_64_    

(32 CPU)
10/28/2013  
10/28/2013  02:25:05 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
10/28/2013  02:25:15 PM    0   51.20    0.00    2.61    0.00    0.00    0.00    0.00    0.00   46.19
10/28/2013  02:25:15 PM    1    6.09    0.00    0.50    0.00    0.00    0.00    0.00    0.00   93.41
10/28/2013  02:25:15 PM    2   25.20    0.00    1.20    0.00    0.00    0.00    0.00    0.00   73.60
10/28/2013  02:25:15 PM    3    0.40    0.00    0.20    0.00    0.00    0.00    0.00    0.00   99.40
10/28/2013  02:25:15 PM    4    3.80    0.00    0.40    0.00    0.00    0.00    0.00    0.00   95.80
10/28/2013  02:25:15 PM    5    3.70    0.00    0.30    0.00    0.00    0.00    0.00    0.00   96.00
10/28/2013  02:25:15 PM    6   21.70    0.00    1.20    0.00    0.00    0.00    0.00    0.00   77.10
10/28/2013  02:25:15 PM    7    0.70    0.00    0.10    0.00    0.00    0.00    0.00    0.00   99.20
10/28/2013  02:25:25 PM    0   45.03    0.00    1.61    0.00    0.00    0.60    0.00    0.00   52.76
10/28/2013  02:25:25 PM    1   17.82    0.00    1.00    0.00    0.00    0.00    0.00    0.00   81.18
10/28/2013  02:25:25 PM    2   29.62    0.00    1.00    0.00    0.00    0.00    0.00    0.00   69.38
10/28/2013  02:25:25 PM    3    9.70    0.00    0.40    0.00    0.00    0.10    0.00    0.00   89.80
10/28/2013  02:25:25 PM    4    2.40    0.00    0.60    0.00    0.00    0.00    0.00    0.00   97.00
10/28/2013  02:25:25 PM    5    2.00    0.00    0.60    0.00    0.00    0.00    0.00    0.00   97.40
10/28/2013  02:25:25 PM    6   22.92    0.00    0.90    0.00    0.00    0.00    0.00    0.00   76.18
10/28/2013  02:25:25 PM    7    2.40    0.00    0.50    0.00    0.00    0.00    0.00    0.00   97.10
> nawk '/CPU/&&/idle/{f=1;next}f{a[$4]+=$13;b[$4]++}END{for(i in a){print i,a[i]/b[i]}}' temp
2 71.49
3 94.6
4 96.4
5 96.7
6 76.64
7 98.15
0 49.475
1 87.295
> 
于 2013-10-29T13:35:32.113 回答
0

经过更多研究,这个片段似乎可以解决问题:

#Parse logs to get CPU averages for cores
PARSE_FILE=`ls ~/logs/*mpstat*`
echo "Parsing ${PARSE_FILE}..."
cat ${PARSE_FILE} | awk '{print $13}' | grep "^[!0-9]" > temp.txt
NUMBER_OF_CORES=8
NUMBER_OF_LINES=`awk ' END { print NR } ' temp.txt`
NUMBER_OF_VALUES=`echo "scale=0;${NUMBER_OF_LINES}/${NUMBER_OF_CORES}" | bc`
TOTAL=0
for i in `seq 1 ${NUMBER_OF_CORES}`
do
  sed -n $i'~'$NUMBER_OF_CORES'p' temp.txt > temp2.txt
  SUM=`awk '{s+=$0} END {print s}' temp2.txt`
  AVERAGE=`echo "scale=0;${SUM}/${NUMBER_OF_VALUES}" | bc`
  echo Core: ${i} Average: `expr 100 - ${AVERAGE}`
  TOTAL=$((TOTAL+${AVERAGE}))
done
TOTAL_AVERAGE=`echo "scale=0;${TOTAL}/${NUMBER_OF_CORES}" | bc`
echo "Total Average: `expr 100 - ${TOTAL_AVERAGE}`"
rm temp*.txt
于 2013-10-29T00:09:21.113 回答