Bash 对列进行分组并在shell中获取特定值

Bash 对列进行分组并在shell中获取特定值,bash,shell,awk,ksh,Bash,Shell,Awk,Ksh,我有一个文件,其中我必须对第1、2和3列进行分组,对第7列求和,得到计数,并得到具有最新日期时间的第4和第5列(第6列) FILE.txt AAA,BBB,CCC,OOO,PPP,20170117012006,12 XXX,YYY,MMM,OOO,PPP,20170117012006,13 AAA,BBB,CCC,III,TTT,20170117020006,14 XXX,YYY,MMM,OOO,PPP,20170117022067,10 预期产量 AAA,BBB,CCC,III,T

我有一个文件,其中我必须对第1、2和3列进行分组,对第7列求和,得到计数,并得到具有最新日期时间的第4和第5列(第6列)

FILE.txt

 AAA,BBB,CCC,OOO,PPP,20170117012006,12
 XXX,YYY,MMM,OOO,PPP,20170117012006,13
 AAA,BBB,CCC,III,TTT,20170117020006,14
 XXX,YYY,MMM,OOO,PPP,20170117022067,10
预期产量

 AAA,BBB,CCC,III,TTT,26,2
 XXX,YYY,MMM,OOO,PPP,23,2
我在这里有一个代码,但只将列1、2、3分组

awk 'BEGIN { FS=OFS=SUBSEP=","}{arr[$1,$2,$3]+=$7 }{arr2[$1,$2,$3]++}END {for (i in arr) print i,arr[i],arr2[i]}' FILE.txt

使用其他数组保存每个组的最新信息

awk 'BEGIN { FS=OFS=SUBSEP="," }
    {
        arr[$1,$2,$3]+=$6; 
        arr2[$1,$2,$3]++;
        if ($6 > latest[$1,$2,$3]) {
            latest[$1,$2,$3] = $6;
            latest_data[$1,$2,$3] = $4 OFS $5;
        }
    }
    END {for (i in arr) print i,arr[i],arr2[i],latest_data[i]}' FILE.txt

使用其他数组保存每个组的最新信息

awk 'BEGIN { FS=OFS=SUBSEP="," }
    {
        arr[$1,$2,$3]+=$6; 
        arr2[$1,$2,$3]++;
        if ($6 > latest[$1,$2,$3]) {
            latest[$1,$2,$3] = $6;
            latest_data[$1,$2,$3] = $4 OFS $5;
        }
    }
    END {for (i in arr) print i,arr[i],arr2[i],latest_data[i]}' FILE.txt
如果要对列1、2和3进行排序,请使用此选项

END { asorti(a,b); for (i in b) { print b[i] substr(a[b[i]],15) }} 
如果要对列1、2和3进行排序,请使用此选项

END { asorti(a,b); for (i in b) { print b[i] substr(a[b[i]],15) }} 

@User101:尝试下面的方法,它将为您提供预期/请求的输出,以及与每个输入文件相同的$1、$2、$3序列

awk -F, 'FNR==NR{A[$1,$2,$3]=A[$1,$2,$3]?A[$1,$2,$3]+$7:$7;;B[$1,$2,$3]++;next} (($1,$2,$3) in A){$NF="";print $0 A[$1,$2,$3] "," B[$1,$2,$3];delete A[$1,$2,$3]}' OFS=, SUBSUP=,   Input_file  Input_file
将字段分隔符设置为“,”。当读取第一个文件时,FNR==NR将为真。创建一个名为A的数组,其索引为$1、$2、$3,并将$7的值连接到该数组中。创建另一个名为B的数组,其索引也是$1、$2、$3,用于计算$1、$2、$3

然后检查A中的($1、$2、$3)是否数组A中存在第一、第二、第三个字段如果是,则根据请求打印当前行(其最后一个字段已设置为NULL)以及数组A和数组B的值

编辑:现在太成功地添加了非线性形式的解决方案

awk -F, 'FNR==NR{
                 A[$1,$2,$3]=A[$1,$2,$3]?A[$1,$2,$3]+$7:$7;
                 B[$1,$2,$3]++;
                 next
                }
                (($1,$2,$3) in A){
                                        $NF="";
                                        print $0 A[$1,$2,$3] "," B[$1,$2,$3];
                                        delete A[$1,$2,$3]
                                 }
        ' OFS=, SUBSUP=,  Input_file  Input_file

@User101:尝试下面的方法,它将为您提供预期/请求的输出,以及与每个输入文件相同的$1、$2、$3序列

awk -F, 'FNR==NR{A[$1,$2,$3]=A[$1,$2,$3]?A[$1,$2,$3]+$7:$7;;B[$1,$2,$3]++;next} (($1,$2,$3) in A){$NF="";print $0 A[$1,$2,$3] "," B[$1,$2,$3];delete A[$1,$2,$3]}' OFS=, SUBSUP=,   Input_file  Input_file
将字段分隔符设置为“,”。当读取第一个文件时,FNR==NR将为真。创建一个名为A的数组,其索引为$1、$2、$3,并将$7的值连接到该数组中。创建另一个名为B的数组,其索引也是$1、$2、$3,用于计算$1、$2、$3

然后检查A中的($1、$2、$3)是否数组A中存在第一、第二、第三个字段如果是,则根据请求打印当前行(其最后一个字段已设置为NULL)以及数组A和数组B的值

编辑:现在太成功地添加了非线性形式的解决方案

awk -F, 'FNR==NR{
                 A[$1,$2,$3]=A[$1,$2,$3]?A[$1,$2,$3]+$7:$7;
                 B[$1,$2,$3]++;
                 next
                }
                (($1,$2,$3) in A){
                                        $NF="";
                                        print $0 A[$1,$2,$3] "," B[$1,$2,$3];
                                        delete A[$1,$2,$3]
                                 }
        ' OFS=, SUBSUP=,  Input_file  Input_file