Добавить номера в специальную запись - PullRequest
0 голосов
/ 28 декабря 2011

Мне нужна помощь в следующем, у меня есть такие записи:

2 8 [4] 2 2 5 8 4 5 6 1

3 41 2 4 8 9

Я должен добавить выделенные столбцы и распечатать сумму и среднее значение.

Итак, если запись содержит «[]»-s, мы должны начинать форму суммирования после этого символа + 1, в противном случае с 4-го столбца до конца.

Я бы ожидал такого вывода:

2 8 [4] 2 2 58 4 5 6 1 31 4.4285

3 4 1 2 4 8 9 23 5.75

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 28 декабря 2011

В одну сторону:

Содержимое script.awk :

{
    ## If exists in the line any number surrounded with square brackets...
    if ( $0 ~ /\[[0-9]+\]/ ) { 
        ## Find its position (beginning the search from the end because I 
        ## want the last one, and begin the count position two numbers later.
        for ( i = NF; i >= 1; i-- ) { 
            if ( $i ~ /^\[[0-9]+\]$/ ) { 
                pos = i + 2 
                break
            }   
        }   
    } else {
        ## Default position when not found any square brackets.
        pos = 4 
    }   

    ## Sum numbers and count them from the position set before until last number.
    for ( j = pos; j <= NF; j++ ) { 
        sum += $j
        count++
    }   

    ## Print to output.
    printf "%s %.5g %.5g\n", $0, sum, (sum / count)
    sum = 0 
    count = 0 
    pos = 0 
}

Содержимое infile :

2 8 [4] 2 2 5 8 4 5 6 1
3 4 1 2 4 8 9
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1

Запустить скрипт:

awk -f script.awk infile

Результат:

2 8 [4] 2 2 5 8 4 5 6 1 31 4.42857                                                                                                                                                                                                           
3 4 1 2 4 8 9 23 5.75
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1 70 5.8333
1 голос
/ 28 декабря 2011

awk oneliner может решить эту проблему:

 awk -F'] ' '{s=$NF; sum=0;avg=0;split(s,n," "); idx=NF>1?2:4;for(x=idx;x<=length(n);x++)sum+=n[x]; avg=sum/(length(n)-idx+1); print $0" "sum" "avg;}  inputFile

тест:

kent$  cat v
2 8 [4] 2 2 5 8 4 5 6 1
3 4 1 2 4 8 9
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1

kent$  awk -F'] ' '{s=$NF; sum=0;avg=0;split(s,n," "); idx=NF>1?2:4;for(x=idx;x<=length(n);x++)sum+=n[x]; avg=sum/(length(n)-idx+1); print $0" "sum" "avg;} ' v
2 8 [4] 2 2 5 8 4 5 6 1 31 4.42857
3 4 1 2 4 8 9 23 5.75
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1 70 5.83333
0 голосов
/ 29 декабря 2011

Возможно, решение sed / bash подойдет вам:

sum(){ { printf "a+=%d;" $@; echo "scale=4; a"; } | bc -l; } 
avg(){ { printf "a+=%d;" $@; echo "scale=4; a/$#"; } | bc -l; } 
set -f sum avg
sed 's/^.*]\s*\S*\s*\(.*\)/& $(sum \1) $(avg \1)/;ta;s/^\(\s*\S*\)\{3\}\s*\(.*\)/& $(sum \2) $(avg \2)/;:a;s/.*/echo "&"/' file | sh
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...