免费注册 查看新帖 |

Chinaunix

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

[文本处理] 提取匹配记录 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-10 10:37 |只看该作者 |倒序浏览
若是只希望两个文件之间输出匹配(第一列)记录,可以直接利用
  1. $ awk 'NR==FNR{key[$1]++;a[$1 FS key[$1]]=$0;next} $1 in key {for (i=1;i<=key[$1];i++) print a[$1 FS i], $0}' OFS="\t" fileA fileB
复制代码
但是若只需要部分匹配,且需要对其中一个文件先进行单位划分,该如何操作呢?
文件一(需要匹配第一列):
  1. NO_222333        222        abc
  2. NO_54321        123        aa
  3. NO_123456        234        bac
  4. NO_5432123        321        bbb
复制代码
文件二(需要首先根据“@”对文件进行划分,再匹配每个单位第一行中内容):
  1. @ab|abc|NO_12345.1|abcd aa bb cc
  2. abcdefghigkabcdefghigkabcdefghigk
  3. abcdefghigkabcdefghigkabcdefghigk
  4. abcdefghigkabcdefghigkabcdefghigk
  5. @ab|cba|NO_54321.1|abcd aa bb aa
  6. cbadefghigkcbadefghigkcbadefg
  7. cbadefghigkcbadefghigkcbadefg
  8. @ab|cba|NO_5432123.2|abcd aa aa
  9. abcdefghigkabcdefghigkabcdefghigk
  10. abcdefghigkabcdefghigkabcdefghigk
  11. cbadefghigkcbadefghigkcbadefg
  12. cbadefghigkcbadefghigkcbadefg
复制代码
输出结果:
  1. @ab|cba|NO_54321.1|abcd aa bb aa
  2. cbadefghigkcbadefghigkcbadefg
  3. cbadefghigkcbadefghigkcbadefg
  4. @ab|cba|NO_5432123.2|abcd aa aa
  5. abcdefghigkabcdefghigkabcdefghigk
  6. abcdefghigkabcdefghigkabcdefghigk
  7. cbadefghigkcbadefghigkcbadefg
  8. cbadefghigkcbadefghigkcbadefg
复制代码

论坛徽章:
0
2 [报告]
发表于 2012-11-10 10:54 |只看该作者
自己先想想

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
3 [报告]
发表于 2012-11-10 12:01 |只看该作者

shell

  1. #!/bin/bash
  2. file1=1.txt
  3. file2=2.txt
  4. list=$(awk '{print $1}' $file1)
  5. for i in $list
  6. do
  7.         awk 'BEGIN{FS=OFS="[|.]";RS="@";ORS=""}$3=="'$i'"{print "@"$0}' $file2
  8. done
复制代码


论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
4 [报告]
发表于 2012-11-10 13:28 |只看该作者
回复 1# 怿_mao44
  1. awk 'NR==FNR{a[$1];next}/@/{if(gensub(/.*(NO[^|]+)\..*/,"\\1",1) in a)(t=1);else{t=0}}t' file1 file2
复制代码

论坛徽章:
0
5 [报告]
发表于 2012-11-10 14:33 |只看该作者
回复 4# yinyuemi


    我的理解,这个命令是对“@”进行一个单位划分后,再提取出第一行中能匹配“NO**”并以“.”结尾的的中间部分。
再与另一个文件的需要匹配部分进行匹配是么?

    但是这个就有限制,必须要是“NO”开头的单一规律部分,若是需要匹配的记录是多种格式就比较麻烦点。
譬如,除了NO_1234,NO_2356这样的部分,还可能是有AA_12345,BB12345,ABC111多种情况

论坛徽章:
0
6 [报告]
发表于 2012-11-10 14:52 |只看该作者
回复 3# yestreenstars


    正在测试,似乎处理速度比较慢。。
  1. #!/bin/bash
  2. file1=1.txt
  3. file2=2.txt
  4. list=$(awk '{print $1}' $file1)                ##提取输入文件一中的第一列记录
  5. for i in $list                ##对提取的第一列记录进行for循环
  6. do
  7.         awk 'BEGIN{FS=OFS="[|.]";RS="@";ORS=""}$3=="'$i'"{print "@"$0}' $file2
  8.                 ##RS指定文件分隔符,以“@”为一个单位(类似于一行),再利用FS,OFS指定列分隔符“|”或者“.”。这样文件二中的第三列即为NO_12345、NO_54321部分,再与之前提取的文件一的第一列进行匹配
  9. done
复制代码
我的理解思路,不知是否正确

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
7 [报告]
发表于 2012-11-10 15:55 |只看该作者
回复 6# 怿_mao44


    没错,就是这个意思,你文件有多大?多少行?

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
8 [报告]
发表于 2012-11-10 16:16 |只看该作者
回复 5# 怿_mao44


    变通变通
awk 'NR==FNR{a[$1];next}/@/{if(gensub(/.*\|([^|]+)\..*/,"\\1",1) in a)(t=1);else{t=0}}t' file1 file2
或:
awk 'NR==FNR{a[$1];next}/@/{split($0,b,"[|.]");if(b[3] in a)(t=1);else{t=0}}t' file1 file2

论坛徽章:
0
9 [报告]
发表于 2012-11-10 16:48 |只看该作者
回复 7# yestreenstars



    要有很多文件进行处理,其中最大的文件大小是“141069785”,行数“1746402”
小数据测试通过,可是大数据量的测试,到现在还没有测试出来一个结果

论坛徽章:
0
10 [报告]
发表于 2012-11-10 16:55 |只看该作者
回复 8# yinyuemi


    我也是希望能理解各位大侠的思路后举一反三
  1. awk 'NR==FNR{a[$1];next}/@/{split($0,b,"[|.]");if(b[3] in a)(t=1);else{t=0}}t' file1 file2
复制代码
这个的解决思路,与yestreenstars 提供的相似

但是
  1. awk 'NR==FNR{a[$1];next}/@/{if(gensub(/.*\|([^|]+)\..*/,"\\1",1) in a)(t=1);else{t=0}}t' file1 file2
复制代码
其中的gensub(/.*\|([^|]+)\..*/部分是进行匹配并分割,但是"\\1",1部分还是不太清楚其中的玄机
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP