给出如下文件:
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|
我想返回每列下的值计数,每列下不同值的计数,然后是每列下所有值的总和。但是我的逻辑/语法一定有问题,纠正它的任何帮助都会很棒!
到目前为止代码(在momemnt它没有返回输出):
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
答案 0 :(得分:4)
使用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
}