unix - различное количество, количество и сумма значений для всех столбцов в файле - PullRequest
0 голосов
/ 26 декабря 2011

с учетом файла, такого как:

sid|storeNo|latitude|longitude
2|1|-28.03720000
9|2
10
jgn352|1|-28.03720000
9|2|fdjkjhn422-405
0000543210|gfdjk39

ожидаемый вывод:

sid|storeNo|latitude|longitude
543240|6|-56.0744|0|
6|5|3|0|
5|3|2|0|

Я хотел бы вернуть количество значений в каждом столбце, количество различных значений в каждомстолбец, а затем сумма всех значений в каждом столбце.Но что-то должно быть не так с моей логикой / синтаксисом, любая помощь, исправляющая это, была бы великолепна!

код до сих пор (в данный момент он не возвращает никакого вывода):

    awk 'BEGIN{FS="|"}
    NR==1{
            for(n = 1; n <= NF; n++) {
               colname[n]=$n
            }
        }
    NR>1 { #skips header
    for(j=1;j<=NF;j++)
    {
        sum[j]+=$j
        rawcount[j]++
        #distinctcount[j, arr[j]]=1
    }
    }
    END{
    for(k=1;k<=NF;k++)
    {
    #for(i in distinctcount)
    # distinctcount[k, i]++
    print colname[j]"|"
print sum[j]"|"
print rawcount[j]"|"
print distinctcount[j]"|"
    }
    }' delimd2iffpipe.dat

1 Ответ

4 голосов
/ 26 декабря 2011

Одно из возможных решений с использованием gawk. Скрипт использует многомерные массивы, и я думаю, что он поддерживается только версией GNU.

Содержимое script.awk (с комментариями):

BEGIN {
        FS="|"
}

## Header.
NR==1{
        ## Get this number to know later how many columns to print.
        cols = NF;

        ## Print header.
        print

        ## Read next record.
        next
}

## Data.
NR>1 { 
    ## For each column, get sum, count and distinct count, save values in arrays.
    for(j=1;j<=NF;j++)
    {
        sum[j] += $j
        rawcount[j]++
        distcount[j][$j]++
    }
}

END{
        print_line(sum)
        print_line(rawcount)

        ## To print distinct count, for each column we count how many values exist in
        ## second dimension.
        for (i = 1; i <= cols; i++ ) {
                printf "%g|", length( distcount[i] ) ? length( distcount[i] ) : 0
        }
        print
}

func print_line(arr)
{
        for ( k = 1; k <= cols; k++ ) {
                printf "%g|", arr[k] ? arr[k] : 0
        }
        print

}

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

awk -f script.awk delimd2iffpipe.dat

Результат:

sid|storeNo|latitude|longitude
543240|6|-56.0744|0|
6|5|3|0|
5|3|2|0|

РЕДАКТИРОВАТЬ : Обходной путь, позволяющий избежать многомерных массивов.Я заменяю его индексом.Это более сложная обработка, но я надеюсь, что она работает со всеми версиями awk:

Вот код.Результат в моей машине такой же, как и в предыдущем скрипте.

BEGIN {
        FS="|"
}

## Header.
NR==1{
        ## Get this number to know later how many columns to print.
        cols = NF;

        ## Print header.
        print

        ## Read next record.
        next
}

## Data.
NR>1 { 
        ## For each column, get sum, count and distinct count, save values in arrays.
    for(j=1;j<=NF;j++)
    {
        sum[j] += $j
        rawcount[j]++
        distcount[j, $j]++
    }
}

END{
        print_line(sum)
        print_line(rawcount)

        for (combined_index in distcount) {
                split( combined_index, idx, SUBSEP )
                dcount[ idx[1] ]++;
        }
        print_line(dcount)
}

func print_line(arr)
{
        for ( k = 1; k <= cols; k++ ) {
                printf "%g|", arr[k] ? arr[k] : 0
        }
        print

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...