为从多个字段派生的键生成 MIN 和 MAX 值

为从多个字段派生的键生成 MIN 和 MAX 值

我有一个很大的平面文件,它是制表符分隔的,如下所示:

APP     SRC     HITS
App1    SRC1    202
App1    SRC1    101
App1    SRC13   90
App1    SRC2    3169
App1    SRC4    1
App1    SRC2    158
App1    SRC2    151
App3    SRC3    1
App3    SRC3    6
App3    SRC3    11
App3    SRC3    16
App3    SRC3    339
App2    SRC3    2
App2    SRC3    10023

我是一个非常新的脚本编写者,所以不知道从哪里开始,而且我似乎无法找到一种解决方案,需要对 APP 和 SRC 列的结果进行分组(即 APP 和 SRC 列成为一个键)。

我只想打印每个应用程序及其所属的 SRC 的 MIN 和 MAX 点击次数。例如

输出应该是这样的。有没有办法通过脚本传递文件来实现此目的?

APP  SRC   MIN   MAX 
App1 SRC1  101   202
App1 SRC2  151   3169
App3 SRC3  1     339
App2 SRC3  2     10023

提前谢谢了!

答案1

awk

awk '
BEGIN{ FS=OFS="\t"; print "APP", "SRC", "MIN", "MAX" }

 NR==1{ next }
 { key=($1 OFS $2) }
 !(key in min) { min[key]=max[key]= $3 }
 min[key]>$3 { min[key]=$3 }
 max[key]<$3 { max[key]=$3 }

END{ for (key in min) print key, min[key], max[key] }' infile

输出:

APP     SRC     MIN     MAX
App2    SRC3    2       10023
App1    SRC1    101     202
App1    SRC2    151     3169
App1    SRC4    1       1
App1    SRC13   90      90
App3    SRC3    1       339

答案2

假设\t不能出现在列名称中,请将其与任何一起使用awk

#!/bin/awk -f
BEGIN {SUBSEP=OFS="\t"; print "APP", "SRC", "MIN", "MAX";}
NR > 1 && (!(($1,$2) in min) || min[$1,$2] > $3) { min[$1,$2] = $3 }
NR > 1 && (!(($1,$2) in max) || max[$1,$2] < $3) { max[$1,$2] = $3 }
END { 
    for(i in min) printf "%s%s%s%s%s\n", i, OFS, min[i], OFS, max[i]
}

答案3

使用(以前称为 Perl_6)

raku -e 'my @a = lines.skip.map(*.words); my @b = @a.map(*.[0..1].join("\t"));  \
         my %c;  %c.=append([Z=>] @b, @a.map(*.[2])); put "APP\t\tSRC\t\tMIN\tMAX";  \
         for %c.sort {say (.key, .value.map(*.Int).min, .value.map(*.Int).max).join: "\t"};' 

以下是使用 Raku 内置哈希函数的方法。基本上,前两列组合起来创建一个,然后使用第三列作为一个或多个s创建key一个哈希。Raku函数将s 添加到相应的键:%cvalueappendvalue

~$ raku -e 'my @a = lines.skip>>.words; my @b = @a.map(*.[0..1].join("\t")); my %c;  %c.=append([Z=>] @b, @a.map(*.[2])); for %c.sort { .say };'  file
App1    SRC1 => [202 101]
App1    SRC13 => 90
App1    SRC2 => [3169 158 151]
App1    SRC4 => 1
App2    SRC3 => [2 10023]
App3    SRC3 => [1 6 11 16 339]

Raku以基本语言提供minmax、 和例程。minmax请注意第一个代码示例:在输出之前强制values非常重要Int,否则 min/max 将无法正常工作。此外,如果需要sprintf超出分离范围的严格格式化,Raku 还具有一个功能(注意:上面的输出在标题中有额外的 s 需要对齐)。\t\t


输入示例:

APP     SRC     HITS
App1    SRC1    202
App1    SRC1    101
App1    SRC13   90
App1    SRC2    3169
App1    SRC4    1
App1    SRC2    158
App1    SRC2    151
App3    SRC3    1
App3    SRC3    6
App3    SRC3    11
App3    SRC3    16
App3    SRC3    339
App2    SRC3    2
App2    SRC3    10023

示例输出:

APP     SRC     MIN MAX
App1    SRC1    101 202
App1    SRC13   90  90
App1    SRC2    151 3169
App1    SRC4    1   1
App2    SRC3    2   10023
App3    SRC3    1   339

https://docs.raku.org/routine/=%3E
https://raku.org

相关内容