linux - unix - 文件中所有列的非重复计数、计数和值总和

标签 linux bash shell unix awk

给定一个文件,例如:

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

最佳答案

一种可能的解决方案是使用 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

}

关于linux - unix - 文件中所有列的非重复计数、计数和值总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8634914/

相关文章:

c++ - boost::bind 返回一个函数对象,它是需要指针的函数的参数

linux - 命令 ps 带选项 -l

linux - bash 脚本读取目录中的所有文件

linux - 不断将控制台的输出写入文件

python - 无法使用 Python ssh 运行远程脚本

mysql - 使用bash获取多条MYSQL记录

linux - 如何在标准输出中使用 'patch' 命令?

linux - 从 cat 加载变量到内存

linux - 处理 FTP 中的日期

python - 将四个并行运行的python程序的输出保存到不同的日志文件