2016-05-27 88 views
2

我有一個像下面這樣的Linux系統的日常文件輸出,並且想知道是否有一種方法可以按照$ 1和平均$ 3以及$ 4 $ 5 $ 6 $ 7以30分鐘的增量對數據進行分組通過使用awk/gawk或類似的東西的shell腳本$ 8?bash組時間和平均值+ sum列

04:04:13 04:10:13 2.13 36 27 18 18 0 
04:09:13 04:15:13 2.37 47 38 13 34 0 
04:14:13 04:20:13 2.19 57 37 23 33 1 
04:19:13 04:25:13 2.43 43 35 13 30 0 
04:24:13 04:30:13 2.29 48 40 19 28 1 
04:29:13 04:35:13 2.33 56 42 16 40 0 
04:34:13 04:40:13 2.21 62 47 30 32 0 
04:39:13 04:45:13 2.25 44 41 19 25 0 
04:44:13 04:50:13 2.20 65 50 32 33 0 
04:49:13 04:55:13 2.47 52 38 16 36 0 
04:54:13 05:00:13 2.07 72 54 40 32 0 
04:59:13 05:05:13 2.35 53 41 19 34 0 

所以基本上這個時候數據會導致這樣的事情:

04:04:13-04:29:13 2.29 287 219 102 183 2 
04:34:13-04:59:13 2.25 348 271 156 192 0 

這是我迄今爲止得到用awk的時間幀之間進行搜索,但我認爲還有一個更簡單得到的分組不awking每30分鐘間隔

awk '$1>=from&&$1<=to' from="04:00:00" to="04:30:00" | awk '{ total += $3; count++ } END { print total/count }'|awk '{printf "%0.2f\n", $1'} 

awk '$1>=from&&$1<=to' from="04:00:00" to="04:30:00" | awk '{ sum+=$4} END {print sum}' 
+0

那麼你嘗試過這麼遠嗎? –

+0

我能夠使用awk單獨獲取硬編碼時間範圍的值,但這是我得到的。我已經更新了我的主線程,以我目前爲止的 – user1999357

+0

,您可以首先從時間中提取分鐘數,例如使用以下代碼:'time = $ 1; min = substr(time,4,2);',用小時和秒錶示,然後寫出比較測試。 –

回答

0

這應該做的方式做你想要的東西:

{ 
    split($1, times, ":"); 
    i = (2 * times[1]); 
    if (times[2] >= 30) i++; 
    if (!start[i] || $1 < start[i]) start[i] = $1; 
    if (!end[i] || $1 > end[i]) end[i] = $1; 
    count[i]++; 
    for (col = 3; col <= 8; col++) { 
     data[i, col] += $col; 
    } 
} 

END { 
    for (i = 1; i <= 48; i++) { 
     if (start[i]) { 
      data[i, 3] = data[i, 3]/count[i]; 
      printf("%s-%s %.2f", start[i], end[i], data[i, 3]); 
      for (col = 4; col <= 8; col++) { 
       printf(" " data[i, col]); 
      } 
      print ""; 
     } 
    } 
} 

正如您所看到的那樣,我將這一天劃分爲48個半小時的時間間隔,並根據第一列中的時間將數據放入其中一個箱中。輸入完畢後,我打印出所有不爲空的垃圾箱。

0

就我個人而言,我會在Python或Perl中執行此操作。在awk中,數組並沒有被排序(當然,你可以使用assorti對數組進行排序......),這使得打印有序桶更加有效。

這裏是概要:

  1. 讀取輸入
  2. 轉換時間戳到秒
  3. 添加到所述數據元素的有序(或排序)關聯陣列中的期望的時間幀的桶(或者,保持運行總計)。
  4. 數據讀取後,按照您的意願進行處理。

這裏是一個Python版本:

#!/usr/bin/python 

from collections import OrderedDict 
import fileinput 
times=[] 
interval=30*60 
od=OrderedDict() 

for line in fileinput.input(): 
    li=line.split() 
    secs=sum(x*y for x,y in zip([3600,60,1], map(int, li[0].split(":")))) 
    times.append([secs, [li[0], float(li[2])]+map(int, li[3:])]) 

current=times[0][0] 
for t, li in times: 
    if t-current<interval: 
     od.setdefault(current, []).append(li) 
    else: 
     current=t 
     od.setdefault(current, []).append(li) 

for s, LoL in od.items(): 
    avg=sum(e[1] for e in LoL)/len(LoL) 
    sums=[sum(e[i] for e in LoL) for i in range(2,7)] 
    print "{}-{} {:.3} {}".format(LoL[0][0], LoL[-1][0], avg, ' '.join(map(str, sums))) 

運行,關於您的示例數據:

$ ./ts.py ts.txt 
04:04:13-04:29:13 2.29 287 219 102 183 2 
04:34:13-04:59:13 2.26 348 271 156 192 0  

的好處是,你可以很容易地改變時間間隔和類似TECHNIC可以使用時間長於天的時間戳。


如果你真的想awk你可以這樣做:

awk 'BEGIN{ interval=30*60 } 
    function fmt(){ 
      line=sprintf("%s-%s %.2f %i %i %i %i %i", ls, $1, sums[3]/count, 
          sums[4], sums[5], sums[6], sums[7], sums[8]) 
    } 
    { 
     split($1,a,":") 
     secs=a[1]*3600+a[2]*60+a[3] 
     if (NR==1) { 
      low=secs 
      ls=$1 
      count=0 
      for (i=3; i<=8; i++) 
       sums[i]=0 
     }      
     for (i=3; i<=8; i++){ 
      sums[i]+=$i 
     } 
     count++   
     if (secs-low<interval) { 
      fmt() 
      }  
     else { 
      print line 
      low=secs 
      ls=$1 
      count=1 
      for (i=3; i<=8; i++) 
       sums[i]=$i       
      }     
    } 
    END{ 
     fmt() 
     print line 
    }' file 
04:04:13-04:29:13 2.29 287 219 102 183 2 
04:34:13-04:59:13 2.26 348 271 156 192 0