返回列表 发帖

gawk如何实现具有相同字段的多行则输出最后字段数值最大的行

本帖最后由 pcl_test 于 2016-7-18 19:41 编辑

有文本a.txt,内容如下
AAA,BBB,CC,D,EEEEEEEE,950
SSS,GGG,CC,F,EEEEEEEE,1000
SSS,GGG,CC,F,EEEEEEEE,800
PPP,YYY,FF,E,DDDDDDDD,1250
KKK,JJJ,HH,D,TTTTTTTT,400
KKK,JJJ,HH,D,TTTTTTTT,1200
KKK,JJJ,HH,D,TTTTTTTT,800COPY
文件中存在以下情况,2条以上的记录前5项相同,最后1项不同,如:
SSS,GGG,CC,F,EEEEEEEE,1000
SSS,GGG,CC,F,EEEEEEEE,800

KKK,JJJ,HH,D,TTTTTTTT,400
KKK,JJJ,HH,D,TTTTTTTT,1200
KKK,JJJ,HH,D,TTTTTTTT,800
希望输出结果:
AAA,BBB,CC,D,EEEEEEEE,950
SSS,GGG,CC,F,EEEEEEEE,1000
PPP,YYY,FF,E,DDDDDDDD,1250
KKK,JJJ,HH,D,TTTTTTTT,1200

即:
1、前5项没有相同记录的,直接输出;
2、前5项有相同记录的,输出第6项数字最大的记录。

希望高手指点,谢谢!

本帖最后由 pcl_test 于 2016-7-18 20:05 编辑
//&cls&cscript -nologo -e:jscript "%~f0"<"1.txt"&pause&exit
var map={}, s='';
while(!WSH.StdIn.AtEndOfStream){
    var str = WSH.StdIn.ReadLine();
    var a = str.replace(/[^\,]+$/, '').replace(/^\s*/, '');
    var b = str.replace(/^.+\,/g, '').replace(/\s*$/, '');
    if(!map[a]){
        map[a]=b;
     }else{
        if(map[a]>=b)map[a]=b;
     }
}
for(var m in map)s+=m+map[m]+'\r\n'
WSH.Echo(s);COPY
1

评分人数

TOP

谢谢pcl_test ,我最想知道的gawk怎样解决这个问题

TOP

本帖最后由 bailong360 于 2015-2-28 15:34 编辑
@echo off
<%0 more +4 >$.awk
gawk -f $.awk a.txt
del $.awk&exit
BEGIN {FS=","}
{
    if (data[$1","$2","$3","$4","$5]==0)
        data[$1","$2","$3","$4","$5]=$6
     else
        data[$1","$2","$3","$4","$5]=$6>data[$1","$2","$3","$4","$5]?$6:data[$1","$2","$3","$4","$5]
   
}
END {
    for (line in data)
        printf("%s,%d\n",line,data[line])>"$new.txt"
}COPY
拙作,楼下既然有更好的代码了,就放在这里当作纪念吧

TOP

本帖最后由 CrLf 于 2015-2-27 19:21 编辑

回复 4# bailong360


    直接用 data[$1,$2,$3,$4,$5] 就好,这里的 , 相当于一个文件分割符

TOP

本帖最后由 bailong360 于 2015-2-27 19:27 编辑

回复 5# CrLf


    我原先也是这样的,后来发现输出以后没有逗号,所以改成了这个样子

看了下兄弟楼下的代码,感叹自己的思路实在是僵硬啊..

TOP

本帖最后由 CrLf 于 2015-2-27 22:31 编辑

gawk -F"," "$6>data[$1,$2,$3,$4,$5]{data[$1,$2,$3,$4,$5]=$0} END{for (line in data)print data[line]>\"$new.txt\"}" a.txt
代码有误,更正见 10 楼
1

评分人数

TOP

本帖最后由 yiwuyun 于 2015-2-28 08:02 编辑

佩服。好像这样也可
gawk -F"," "$6>data[$1$2]{data[$1$2]=$0} END{for (line in data)print data[line]}" a.txtCOPY
改成这样:
gawk -F"," "$6>a[split(data[$1$2],a,\",\")]{data[$1$2]=$0} END{for (line in data)print data[line]}" 2.txtCOPY
1

评分人数

    • CrLf: a[split(data[$1$2],a,\&quot;,\&quot;)] .技术 + 1

TOP

感谢大家的帮助,今天没法评分了,明天补上

TOP

本帖最后由 CrLf 于 2015-2-27 22:30 编辑

卧槽,大伙没发现我写错了吗,用 $6 和 $0 来比较的...
修改下,还是像 4 楼那样用逗号分隔吧
gawk -F"," -v d="," "$6>data[$1 d $2 d $3 d $4 d $5]{data[$1 d $2 d $3 d $4 d $5]=$6} END{for (line in data)print line d data[line]}" a.txtCOPY
或用 gsub
gawk -F"," "$6>data[$1,$2,$3,$4,$5]{data[$1,$2,$3,$4,$5]=$6} END{for (line in data){l=line;gsub(/\x1c/,\",\",l);print l \",\" data[line]}}" a.txtCOPY
分隔符不同,排序居然还不一样
1

评分人数

TOP

本帖最后由 yiwuyun 于 2015-2-28 08:26 编辑

$6和$0比较,就是$6和$6比较。逗号分隔符的计算就是以最后一个为准。认识错了。
gawk -F"," "$6>int(data[$1$2]){data[$1$2]=$0} END{for(line in data)print data[line]}" a.txt

TOP

回复 10# CrLf


感谢帮助,我对这个还是了解的太少了

TOP

回复 8# yiwuyun

谢谢帮助,我觉得还是data[$1$2$3$4$5]比较好,否则第三到5列要是有不一样的就无法区分了

TOP

本帖最后由 CrLf 于 2015-2-28 13:36 编辑

回复 8# yiwuyun


    a[split(data[$1$2],a,\",\")] 好精巧!可以去掉 \",\",因为你已经设了 FS 了
    但 $1$2 是没有分隔符的,怎么区分 SSS,GGG 和 SSSG,GG 呢?
1

评分人数

TOP

嗯。多谢指正,考虑不周,实际应用应多取几段,或者再多加几根下划线。这样重复的概率就小多了。

TOP

返回列表