免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4535 | 回复: 11

跨文件关键字匹配--方法总结 [复制链接]

论坛徽章:
0
发表于 2012-06-03 12:48 |显示全部楼层

近段时间碰到了很多情况是需要跨两个输入文件,通过关键字来将相同内容合并,于是在此区分不同情况,将解决办法总结如下:
          希望能帮助其他跟我一样有过困惑的朋友。。
   解决方法有很多,这里只是提出其中一部分,供大家讨论,提出意见,或者还有怎样情况的匹配条件需要另外注意   ??  

解决方法中,表明了每一个提供答案的贡献者,再次感谢他们

第一种情况:匹配条件的关键字在两个文件中都是唯一,不重复的
按照某一列的内容,合并相同内容的两个文件中的行,均已制表符进行划分的

如文件1:(此文件中第三列为关键字)
  1. Qwe        wer        aa        rty
  2. Giy        rug        cc        uop
  3. Rtu        egj        ee        ioj
  4. Drt        tue        ff        yti
复制代码
文件2::(而此文件中第二列为关键字)
  1. 123        aa        wyf        yui
  2. 234        bb        yoi        dty
  3. 456        dd        uoj        yio
  4. 567        ee        drt        hio
复制代码
分别得到三个结果:
    结果文件一:  在两个文件中有匹配的记录
  1. Qwe        wer        aa        rty        123        aa        wyf        yui
  2. Rtu        egi        ee        ioj        567        ee        drt        hio
复制代码
结果文件二:   只在输入文件一中存在的记录
  1. Giy        rug        cc        uop
  2. Drt        tue        ff        yti
复制代码
结果文件三:   只在输入文件二中存在的记录
  1. 234        bb        yoi        dty
  2. 456        dd        uoj        yio
复制代码
解决方法:
1.由“yinyuemi ”提供
  1. $ join -1 3 -2 2 file1 file2 # comm
  2. $ grep -vf <(cut -f3 file1) file2 # file2 only
  3. $ grep -vf <(cut -f2 file2) file1 # file1 only
复制代码
2.由“yangkyo821 ”提供
  1. $ awk 'NR==FNR{f1[$3]=$0;next}$2 in f1{printf $0"\t"f1[$2] RS > "outfile1";delete f1[$2];next}{print > "outfile3"}END{for(s in f1)print f1[s] > "outfile2"}' file1 file2
复制代码
3.由“jiejie455”提供
  1. $ awk 'NR==FNR{a[$3]=$0;ind[$3]};NR>FNR{b[$2]=$0;ind[$2]}END{for(i in ind){if(a[i]&&b[i]){print a[i],b[i]}}}' file1 file2 ##comm
  2. $ awk 'NR==FNR{a[$3]=$0;ind[$3]};NR>FNR{b[$2]=$0;ind[$2]}END{for(i in ind){if(a[i]&&!b[i]){print a[i],b[i]}}}' file1 file2 ##file1_only
  3. $ awk 'NR==FNR{a[$3]=$0;ind[$3]};NR>FNR{b[$2]=$0;ind[$2]}END{for(i in ind){if(!a[i]&&b[i]){print a[i],b[i]}}}' file1 file2 ## file2_only
复制代码
第二种情况:需要同时匹配两列的关键字,而且第二列,第三列之间在同一个输入文件中是存在重复记录的
文件一的第二列必须匹配文件二的第三列(file_1$2==file_2$3),而同时文件一的第三列必须匹配文件二的第四列(file_1$3==file_2$4)。

输入文件一:

  1. 11        aa        bb        123        456
  2. 22        aa        cc        456        789
  3. 33        ee        bb        123        789
  4. 44        bb        aa        456        132
复制代码
输入文件二:
  1. +        1        aa        cc
  2. +        2        ee        bb
复制代码
希望输出的结果文件是:

  1. 22        aa        cc        456        789        +        1        aa        cc
  2. 33        ee        bb        123        789        +        2        ee        bb
复制代码
解决方法:
1.由"rdcwayx "提供
  1. $ awk 'NR==FNR{a[$2 FS $3]=$0;next}$3 FS $4 in a {print a[$3 FS $4] "\t"  $0}' file1 file2
复制代码
2.由“zhaopingzi ”提供
  1. $ awk 'ARGIND==1 {a[$2$3]=$0} ARGIND>1&&($3$4 in a) {print a[$3$4],$0}' file1 file2
复制代码
第三种情况:匹配关键字的列在其中一个输入文件中含有重复的记录,匹配全部的记录

输入文件fileA,此时第三列中就出现有重复的“aa”
  1. 11        123        aa        321
  2. 12        223        aa        123
  3. 22         332        bb        231
复制代码
输入文件fileB
  1. aa        AA
  2. bb        BB
复制代码
根据文件一中的第三列和文件二中的第一列进行匹配,匹配成功的合并一个文件输出
希望的结果文件result
  1. 11        123        aa        321        aa        AA
  2. 12        223        aa        123        aa        AA
  3. 22         332        bb        231        bb        BB
复制代码
解决方法:
1.由“winway1988 ”提供
  1. $ awk 'NR==FNR{a[$1]=$0}NR>FNR{print $0 "\t" a[$3]}' fileB fileA
复制代码
2.由“zooyo ”提供
  1. $ awk 'BEGIN{while(getline <"fileB")a[$1]=$0}{$0=$0"\t"a[$3]}1' fileA  
复制代码
第四种情况:当两个不同文件中存在关键字需要匹配,且需要匹配的关键字,在两个输入文件中均存在重复的记录
输入文件一:此时第二列中"aa bb"均出现重复
  1. 1        aa        123
  2. 2        aa        234
  3. 3        bb        345
  4. 4        bb        445
  5. 5        dd        234
复制代码
输入文件二:此时第三列的"bb"仍然出现有重复
  1. A1        111        aa
  2. B1        222        bb
  3. B2        333        bb
  4. B2        333        cc
复制代码
根据输入文件一中第2列,输入文件二中第3列作为关键字进行匹配,输出全部匹配的记录
期望输出结果:
  1. 1        aa        123        A1        111        aa
  2. 2        aa        234        A1        111        aa
  3. 3        bb        345        B1        222        bb
  4. 4        bb        445        B1        222        bb
  5. 3        bb        345        B2        333        bb
  6. 4        bb        445        B2        333        bb
复制代码
解决方法:
1.由“rdcwayx ”提供
  1. $ awk 'NR==FNR{key[$2]++;a[$2 FS key[$2]]=$0;next} $3 in key {for (i=1;i<=key[$3];i++) print a[$3 FS i], $0}' OFS="\t"  file1.txt file2.txt
复制代码
2.由“jiejie455”提供
  1. awk 'NR==FNR{a[$2]=a[$2]?$0"|"a[$2]:$0};NR>FNR{if(a[$3]){split(a[$3],b,"|");for(i=1;i<=length(b);i++){print b[i]"\t"$0}}}' file1 file2
复制代码

论坛徽章:
0
发表于 2012-06-03 15:31 |显示全部楼层
学习学习!

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
发表于 2012-06-03 15:45 |显示全部楼层
  还有我的代码。

论坛徽章:
0
发表于 2012-06-10 14:46 |显示全部楼层
顶啊   很好很强大  智慧的结晶

论坛徽章:
1
摩羯座
日期:2014-12-29 15:59:36
发表于 2012-06-10 17:33 |显示全部楼层
牛,好好学习了

论坛徽章:
13
15-16赛季CBA联赛之同曦
日期:2016-01-28 19:52:032015亚冠之北京国安
日期:2015-10-07 14:28:19NBA常规赛纪念章
日期:2015-05-04 22:32:03处女座
日期:2015-01-15 19:45:44卯兔
日期:2014-10-28 16:17:14白羊座
日期:2014-05-24 15:10:46寅虎
日期:2014-05-10 09:50:35白羊座
日期:2014-03-12 20:52:17午马
日期:2014-03-01 08:37:27射手座
日期:2014-02-19 19:26:54子鼠
日期:2013-11-30 09:03:56狮子座
日期:2013-09-08 08:37:52
发表于 2012-06-27 10:18 |显示全部楼层
总结的真及时,赞! ^_^

论坛徽章:
0
发表于 2012-06-27 12:13 |显示全部楼层
第三种匹配是不是有些问题:
楼主给的a,b2个文件正好是都有匹配,如果a文件多一条记录,比如
33        121        ee        121
那这条记录应该是不被显示出来的,因为b文件无匹配.

修改如下:
awk 'NR==FNR{a[$1]=$0}NR>FNR&&a[$3]{print $0 "\t" a[$3]}' 2.txt 1.txt
awk 'BEGIN{while(getline <"fileB")a[$1]=$0}{$0=$0"\t"a[$3]}a[$3]' fileA  

论坛徽章:
28
ChinaUnix元老
日期:2015-02-02 08:55:392017金鸡报晓
日期:2017-01-10 15:13:29CU十四周年纪念徽章
日期:2018-08-29 22:12:2715-16赛季CBA联赛之深圳
日期:2018-09-20 12:21:09
发表于 2012-06-27 13:45 |显示全部楼层
有总结才有进步,加油。

求职 : 项目经理
论坛徽章:
21
狮子座
日期:2014-01-14 08:42:1615-16赛季CBA联赛之八一
日期:2016-12-15 16:11:1315-16赛季CBA联赛之佛山
日期:2016-12-19 08:58:1315-16赛季CBA联赛之佛山
日期:2017-01-12 11:34:1415-16赛季CBA联赛之福建
日期:2017-02-22 14:05:4415-16赛季CBA联赛之福建
日期:2017-06-09 08:59:4015-16赛季CBA联赛之深圳
日期:2017-07-17 11:19:3615-16赛季CBA联赛之新疆
日期:2018-03-09 09:36:5115-16赛季CBA联赛之江苏
日期:2018-07-18 10:44:4615-16赛季CBA联赛之浙江
日期:2016-11-18 15:14:1615-16赛季CBA联赛之四川
日期:2016-06-27 11:43:3115-16赛季CBA联赛之新疆
日期:2016-04-20 10:18:20
发表于 2012-06-27 15:16 |显示全部楼层
都是大牛!!!!

论坛徽章:
0
发表于 2012-07-12 15:33 |显示全部楼层
先记下来,或许以后有用
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,7折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时七折期:2019年8月31日前


----------------------------------------

大会官网>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP