2013-02-22 2 views
0

У меня возникли проблемы с вычислением среднего числа конкретных чисел в столбце НИЖЕ определенного текстового идентификатора с использованием awk. У меня есть два столбца данных, и я пытаюсь запустить среднюю привязку к общему идентификатору, который повторяется, то есть 01/1991. Таким образом, awk должен вычитать среднее значение всех строк, начинающихся с 01/1991, которое повторяется, используя следующие 21 строки с общим количеством строк для среднего значения = 22 за общее количество лет 1991-2012. Желаемый результат представляет собой среднее значение каждой записи TextID/название для всех январского (01) за каждый год 1991 - 2012 показать ниже:Awk Calc Средние строки ниже определенной строки

TextID/Имя 1 Avg: 50.34 TextID/Имя 2 Avg: 45.67 TextID/Имя 3 среднее: 39,97 ...

выборочные данные:

TextID/Name 1 
01/1991, 57.67 
01/1992, 56.43 
01/1993, 49.41 
.. 
01/2012, 39.88 
TextID/Name 2 
01/1991, 45.66 
01/1992, 34.77 
01/1993, 56.21 
.. 
01/2012, 42.11 
TextID/Name 3 
01/1991, 32.22 
01/1992, 23.71 
01/1993, 29.55 
.. 
01/2012, 35.10 
continues with the same data for TextID/Name 4 

Я получаю ответ, используя этот код показан ниже, но в среднем начинает подсчитывать ПЕРЕД конкретной линии идентификатора ине на линии и ниже этой линии (01/1991).

awk '$1="01/1991" {sum+=$2} (NR%22==0){avg=sum/22;print"Average: "avg;sum=0;next}' myfile 

Спасибо и объяснения решения с благодарностью! Я отредактировал оригинальный ответ с большим количеством описаний - еще раз спасибо.

+0

Я думаю, что вы хотите 'awk '$ 1 ==" .... '.' $ 1 = "xxx" 'присваивает поле 1. Удачи. – shellter

+0

спасибо за ваш ответ, но который вычисляет все нули для среднего значения, когда я сделайте это. – user2100039

+0

Другое дело о '$ 1 =" 01/1991 "состоит в том, что, поскольку это назначение, оно всегда будет истинным, и все записи будут обрабатывать' sum + = $ 2'. Это может помочь, если вы создадите свой вопрос немного больше. В настоящее время мы понятия не имеем, почему вы выбрали 22 (я могу догадаться). И что еще более важно, мы не имеем представления о вашем желаемом выходе и реальной картине вашего существующего вывода. Или вы можете просто добавить некоторые заявления о печати на все ваши переменные для самостоятельной отладки проблемы. Удачи. – shellter

ответ

0

Если вам разрешено использовать Perl вместо Awk, вы могли бы сделать:

#!/usr/bin/env perl 

$start = 0; 
$have_started = 0; 
$count = 0; 
$sum = 0; 

while (<>) { 
    $line = $_; 

    # Grab the value after the date and comma 
    if ($line = /\d+\/\d+,\s+([\d\.]+)/) { 
    $val = $+; 
    } 

    # Start summing values after 01/1991 
    if (/01\/1991,\s+([\d\.]+)/) { 
    $have_started = 1; 
    $val = $+; 
    } 

    # If we have started counting, 
    if ($have_started) { 
    $count++; 
    $sum += $+; 
    } 
} 

print "Average of all values = " . $sum/$count; 

Выполнить это примерно так:

$ cat your-text-file.txt | above-perl-script.pl 
1

Если вы посмотрите на файл, то первое поле «01/1991» с запятой в конце, а не «01/1991». Кроме того, NR% 22 == 0 будет смотреть на числа строк, делящиеся на 22, а не на 22 строки после точки, о которой вы думаете.

Вы можете сделать что-то вроде этого, вместо:

awk ' 
    BEGIN { l=-1; } 
    $1 == "01/1991," { 
    l=22; 
    s=0; 
    } 

    l > 0 { s+=$2; l--; } 
    l == 0 { print s/22; l--; }' 

Он имеет счетчик л, что она устанавливает на количество линий для подсчета, то это подводит итог, что количество строк.

Возможно, вы захотите просто суммировать все строки от одного 01/1991 до следующего, хотя это может быть более надежным.

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