2013-10-28 136 views
0

我想設計一個Unix shell腳本(最好是通用的sh),將採取一個文件的內容是數字,每行一個。這些數字與mpstat的所獲得的CPU空閒時間:Unix Shell:總結值,每行一個,但跳過每第n行

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 ,Core 2的第2行等等...對於X個內核(在我的情況下爲8) - 所以每個第9行再次對於Core 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」。

回答

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 
> 
+0

有很多在這裏很好的答案,但我的需求,這個工作是最好的。這很簡單直接。在末尾添加「| sort -n」將按照CPU號碼的順序進行添加。 – Matt

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 
1

下面countCores.sh腳本是基於你在TEMP.TXT 給這可能不是你想要的數據,但會給你一些想法。我不確定 你想要的平均總平均值是多少,所以我選擇在所有8個核心的第一列中顯示 的平均值。我還用cat -n來表示核心號碼。 希望這會有所幫助。 VonBell

#!/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 
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}