免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2277 | 回复: 6
打印 上一主题 下一主题

请问我该怎么删除掉特定字段重复的行? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-27 00:18 |只看该作者 |倒序浏览
看遍了所有UNIQ的参数,发现没有一个参数针对某一字段重复删除所在行.
例如:
file1

1111|2222|3333|4444|
1234|5678|3333|2321|
3244|1234|4322|3242|
0000|8888|3333|2345|

我希望删除其中$3重复的行,只保留一个,而不管其他字段是否一样.即希望得到下面文件:
file2
1111|2222|3333|4444|
3244|1234|4322|3242|

uniq file1 file2是个很好的命令,但是他只能比较整行重复才能使用
uniq -f field 只能忽略掉前面的字段
怎么才能实现这个功能呢?
请赐教!

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
2 [报告]
发表于 2006-04-27 00:22 |只看该作者

  1. awk -F\| '!a[$3]++' filename
复制代码

论坛徽章:
0
3 [报告]
发表于 2006-04-27 00:49 |只看该作者
太感谢老大了,我为这个东西搞了4个小时了.结果被一句话搞顶.我能不能再问个问题.
awk 'BEGIN {OFS=FS="|"} { print $3 }' file1 > ls
sort ls >ls.txt
uniq ls.txt ls
awk 'BEGIN {OFS=FS="|"} {
  while ((getline < "file1" ) > 0)
        {
           ls1[$3]=$1
           ls2[$3]=$2
           ls3[$3]=$3
           ls4[$3]=$4
        }
( $1 != ls1[$1] ) {
        s1=ls1[$1]
        s2=ls2[$1]
        s3=ls3[$1]
        s4=ls4[$1]
       printf ("s%|s%|s%|s%|",s1,s2,s3,s4)
      }' ls > file2
这个方法虽然很苯,但是应该没有问题的啊.结果我发现ls中有一行始终没有转进file中,即file2总比标准文件ls少一行,请问这是为什么.谢谢

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
4 [报告]
发表于 2006-04-27 10:57 |只看该作者
while ((getline < "file1" ) > 0)
        {
           ls1[$3]=$1
           ls2[$3]=$2
           ls3[$3]=$3
           ls4[$3]=$4
        }
以上部分读入所有行,并把每行四个域以第三个域为索引存入四个数组,如果索引存在的话将覆盖其中的内容

( $1 != ls1[$1] ) {
        s1=ls1[$1]
        s2=ls2[$1]
        s3=ls3[$1]
        s4=ls4[$1]
       printf ("s%|s%|s%|s%|",s1,s2,s3,s4)
      }
如果最后一行的第一个域与数组中以它为索引的内容不同,打印最后一行的四个域

这是我对你的脚本的讲解,不知道你怎么理解?

论坛徽章:
0
5 [报告]
发表于 2006-04-27 14:15 |只看该作者
对不起,其中有些语法错误,现在改过来
awk 'BEGIN {OFS=FS="|"} { print $3 }' file1 > ls
sort ls >ls.txt
uniq ls.txt ls
awk 'BEGIN {OFS=FS="|"} {
  while ((getline < "file1" ) > 0)
        {
           ls1[$3]=$1
           ls2[$3]=$2
           ls3[$3]=$3
           ls4[$3]=$4
        }
       }
( $1 == ls1[$1] ) {
        s1=ls1[$1]
        s2=ls2[$1]
        s3=ls3[$1]
        s4=ls4[$1]
       printf ("s%|s%|s%|s%|",s1,s2,s3,s4)
      }' ls > file2
我大概的理解是:while ((getline < "file1" ) > 0)将 以$3为索引读如所有行
( $1 == ls1[$1] )是如果 第一个字段与ls1[$1]相等,则打印内容.我以为这是ls与fiel1相关联条件。按我的理解,ls是从file1生成的唯一的不重复的字段.再把file1中其他的字段加到ls每一行.
就像你说的($1 != ls1[$1])如果最后一行的第一个域与数组中以它为索引的内容不同,打印最后一行的四个域
.脚本确实只打印了最后一行.我以为他该打印所有只要ls与file1中对应指定字段不同的行.为什么这样说呢?

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
6 [报告]
发表于 2006-04-27 14:19 |只看该作者
如果有兴趣读一下新手导航里那篇awk教程吧?

论坛徽章:
0
7 [报告]
发表于 2006-04-27 14:26 |只看该作者
为此也专门买了一本书,现在我的实际情况是数据移植.时间非常紧张,SHELL只能现学现用,不能用专门时间来搞.只要把问题解决就开始搞,程序不是最终的目的.不过很多问题一问就被高手们解决了.不过偶都一一备案,SHELL太强大高深了.我也一定要学好他.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP