Одно из возможных решений с использованием 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
}