标题: gawk如何实现具有相同字段的多行则输出最后字段数值最大的行 [打印本页]
作者: 愤怒的CMD 时间: 2015-2-27 09:12 标题: 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,800
复制代码
文件中存在以下情况,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 时间: 2015-2-27 16:22
本帖最后由 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);
复制代码
作者: 愤怒的CMD 时间: 2015-2-27 16:34
谢谢pcl_test ,我最想知道的gawk怎样解决这个问题
作者: bailong360 时间: 2015-2-27 18:30
本帖最后由 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"
- }
复制代码
拙作,楼下既然有更好的代码了,就放在这里当作纪念吧
作者: CrLf 时间: 2015-2-27 19:16
本帖最后由 CrLf 于 2015-2-27 19:21 编辑
回复 4# bailong360
直接用 data[$1,$2,$3,$4,$5] 就好,这里的 , 相当于一个文件分割符
作者: bailong360 时间: 2015-2-27 19:18
本帖最后由 bailong360 于 2015-2-27 19:27 编辑
回复 5# CrLf
我原先也是这样的,后来发现输出以后没有逗号,所以改成了这个样子
看了下兄弟楼下的代码,感叹自己的思路实在是僵硬啊..
作者: CrLf 时间: 2015-2-27 19:21
本帖最后由 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 楼
作者: yiwuyun 时间: 2015-2-27 20:20
本帖最后由 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.txt
复制代码
改成这样:- gawk -F"," "$6>a[split(data[$1$2],a,\",\")]{data[$1$2]=$0} END{for (line in data)print data[line]}" 2.txt
复制代码
作者: 愤怒的CMD 时间: 2015-2-27 20:40
感谢大家的帮助,今天没法评分了,明天补上
作者: CrLf 时间: 2015-2-27 22:21
本帖最后由 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.txt
复制代码
或用 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.txt
复制代码
分隔符不同,排序居然还不一样
作者: yiwuyun 时间: 2015-2-28 07:41
本帖最后由 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
作者: 愤怒的CMD 时间: 2015-2-28 08:25
回复 10# CrLf
感谢帮助,我对这个还是了解的太少了
作者: 愤怒的CMD 时间: 2015-2-28 08:27
回复 8# yiwuyun
谢谢帮助,我觉得还是data[$1$2$3$4$5]比较好,否则第三到5列要是有不一样的就无法区分了
作者: CrLf 时间: 2015-2-28 13:34
本帖最后由 CrLf 于 2015-2-28 13:36 编辑
回复 8# yiwuyun
a[split(data[$1$2],a,\",\")] 好精巧!可以去掉 \",\",因为你已经设了 FS 了
但 $1$2 是没有分隔符的,怎么区分 SSS,GGG 和 SSSG,GG 呢?
作者: yiwuyun 时间: 2015-2-28 15:13
嗯。多谢指正,考虑不周,实际应用应多取几段,或者再多加几根下划线。这样重复的概率就小多了。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |