2015-02-23 2 views
0

Это пример данных IOstat, выполняемых в течение определенного периода времени. (Я удалил пустые строки, пробелы и т. Д.) Мне нужно среднее значение каждого столбца для каждого диска.Средние столбцы на основе одного столбца

Любая идея, как это сделать, используя awk/sed?

125.7 39.9 979.3 394.4 0.0 2.2 0.1 13.462 0 27 c1t5000CCA01BBC5A7Cd0 
    127.1 39.8 977.6 394.5 0.0 2.2 0.0 13.441 0 27 c1t5000CCA01BBC59ACd0 
    126.7 39.9 975.8 394.0 0.0 2.2 0.1 12.926 0 26 c1t5000CCA01BBC59DCd0 
    126.2 40.0 970.5 394.0 0.0 2.2 0.0 13.115 0 26 c1t5000CCA01BBC5A2Cd0 
    7.9 0.0 10.9 0.0 0.0 0.0 0.0 0.152 0 0 c3t0d0 
    124.7 183.0 1236.0 2075.1 0.0 7.6 0.0 24.838 0 35 c1t5000CCA01BBC5A2Cd0 
    0.0 148.4 0.0 322.4 0.0 6.6 0.0 44.482 0 38 c3t0d0 
    32.0 9.7 178.1 3.9 0.0 0.3 0.0 7.822 0 15 c1t5000CCA01BBC5980d0 
    62.1 0.0 31.0 0.0 0.0 0.0 0.0 0.000 0 0 c1t5000CCA01BBC5950d0 
    37.8 9.7 346.8 3.9 0.0 0.3 0.0 6.821 0 15 c1t5000CCA01BBC5A44d0 
    54.3 4.8 649.4 0.0 0.0 1.6 0.0 27.885 0 19 c1t5000CCA01BBC58E4d0 
    50.4 9.7 622.2 3.9 0.0 0.7 0.0 11.007 0 19 c1t5000CCA01BBC5A48d0 
    90.2 4.8 1922.2 0.0 0.0 2.8 0.0 29.611 0 25 c1t5000CCA01BBC5AA8d0 
    62.1 161.0 31.0 354.4 0.0 0.8 0.0 3.777 0 5 c1t5000CCA01BBC5918d0 
    102.8 430.6 1897.1 26280.3 0.0 1.7 0.0 3.281 0 11 c1t5000CCA01324687Cd0 
    496.5 20587.8 1988.1 96156.7 0.1 13.4 0.0 0.637 6 46 c1t5000CCA0132475ACd0 
    487.8 20588.8 1961.0 96160.6 0.1 13.5 0.0 0.640 6 46 c1t5000CCA0132477ECd0 

EDIT:

входного файла

c1 c2 c3 c4 diskname 

1 1 1 1 d1 
1 2 3 2 d2 
2 1 4 3 d3 
3 2 3 2 d1 
1 2 3 2 d2 
1 2 3 2 d3 

Ожидаемый результат

Avg_c1 Avg_c2 Avg_c3 Avg_c4 diskname 
    2  1.5  2  1.5 d1 
    1  2  3  2  d2 
1.5 1.5 3.5  2.5 d3 

Где

X={d1,d2,d3} 
Y={c1,c2,c3,c4} 

Avg_[Y] for X = sum of column Y where diskname is X/number of entries of X 

Мне нужно что-то, что работает для любого количества столбцов и сообщений.

+1

@EdMorton сделал изменения – Iceman

ответ

1

С AWK:

awk '{ fields[$NF] = NF; ++ctr[$NF]; for(i = 1; i < NF; ++i) { sum[$NF,i] += $i } } END { PROCINFO["sorted_in"] = "@ind_str_asc"; for(c in ctr) { for(i = 1; i < fields[c]; ++i) { printf("%.3f\t", sum[c,i]/ctr[c]) } print c } }' filename 

То есть:

{ 
    ++ctr[$NF]     # in every line, count how often the disk 
    for(i = 1; i < NF; ++i) { # appeared and sum up the fields 
    sum[$NF,i] += $i 
    } 
} 
END {       # in the end, print the tallies 
           # divided by the counter (the averages) 

    # PROCINFO["sorted_in"] is GNU-specific, for sorted traversal. If that is a 
    # problem or not necessary, it is safe to remove it. 
    PROCINFO["sorted_in"] = "@ind_str_asc" 

    for(c in ctr) { 
    for(i = 1; i < NF; ++i) { 
     printf("%.3f\t", sum[c,i]/ctr[c]) 
    } 
    print c 
    } 
} 

Чтобы пропустить строку заголовка, положить

NR > 1 

перед первым { (пропустить два, использовать NR > 2. Я не уверен, что это должно быть частью вашего ввода).

+0

Спасибо! Оно работает. – Iceman

1

Вот как получить данные:

$ cat tst.awk   
NR==1 { 
    key = $NF 
    $NF = "" 
    gsub(/[^[:space:]]+/,"Avg_&") 
    print $0 key 
    next 
} 
NF { 
    for (i=1;i<NF;i++) { 
     sum[$NF,i] += $i 
    } 
    cnt[$NF]++ 
} 
END { 
    for (key in cnt) { 
     for (i=1;i<NF;i++) { 
      printf "%s%s", sum[key,i]/cnt[key], OFS 
     } 
     print key 
    } 
} 
$ awk -f tst.awk file 
Avg_c1 Avg_c2 Avg_c3 Avg_c4 diskname 
2 1.5 2 1.5 d1 
1 2 3 2 d2 
1.5 1.5 3.5 2.5 d3 

Дайте нам знать, если у вас есть проблемы форматирования вывода с помощью printf или трубопровода к column или любой другой ...

+1

Спасибо! Оно работает. – Iceman

Смежные вопросы