免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3294 | 回复: 6

[文本处理] 如何将A文件根据B文件得到C文件 [复制链接]

论坛徽章:
0
发表于 2019-02-15 15:31 |显示全部楼层
10可用积分
A文件:3列,第一列是序列ID,第二列是序列长度,第三列是序列注释信息

Chr01_9654239_9660689        645 GAG_copia/GAG_tork/AP_copia/INT_tat/INT_17_6/INT_codi_d/INT_retrofit/INT_copia/INT_sire/INT_1731/INT_oryco/RT_hydra/RT_pCretro/RT_copia/RNaseH_codi_c /RNaseH_retrofit/RNaseH_oryco/RNaseH_copia/RNaseH_codi_d
Chr01_10815525_10825383 9859 RNaseH_gypsy/RNaseH_galadriel/RNaseH_gmr1/RNaseH_17_6/RNaseH_pyret/RNaseH_maggy/RNaseH_micropia_mdg3/RNaseH_v_clade/RNaseH_osvaldo/RNaseH_b_clade/RNaseH_TF/
RNaseH_a_clade/RNaseH_pyggy/INT_osvaldo/INT_cer2_3/INT_crm/INT_reina
Chr01_11277413_11279136        1724        RNaseH_tork/RNaseH_retrofit/RNaseH_oryco/RNaseH_sire/RNaseH_1731/RNaseH_copia/RNaseH_codi_d/RNaseH_codi_c
Chr01_13549455_13553995        4541 GAG_sire/GAG_oryco/AP_oryco/AP_copia/INT_oryco/INT_hydra/INT_copia/INT_1731/INT_retrofit/INT_tork/INT_sire/INT_csrn1/INT_pseudovirus/INT_pCretro/INT_codi_d/
RT_tork/RT_oryco/RT_pCretro/RT_1731/RT_hydra/RT_sire/RT_copia/RT_retrofit/RT_codi_d/RT_codi_c/RT_galea/RT_pseudovirus/RNaseH_copia/RNaseH_oryco/RNaseH_sire/RNaseH_retrofit/RNaseH_tork/RNaseH_1731/RNaseH_pCretro/RNaseH_codi_d/RNaseH_hydra
Chr01_13578874_13583841        4968 GAG_retrofit/AP_retrofit/INT_tork/INT_pseudovirus/INT_1731/INT_oryco/INT_copia/INT_retrofit/RT_codi_c/RT_1731/RT_pseudovirus/RT_oryco/
RT_codi_d/RT_copia/RT_tork/RT_retrofit/RT_sire/RT_hydra/RT_pCretro/RNaseH_codi_I/RNaseH_pseudovirus/RNaseH_tork/RNaseH_codi_d/RNaseH_1731/RNaseH_hydra/RNaseH_sire/RNaseH_pCretro/RNaseH_oryco/RNaseH_retrofit/RNaseH_copia
Chr01_13708617_13713687        5071        GAG_reina/GAG_del/AP_galadriel/AP_del/AP_reina/INT_del/RT_alpharetroviridae/RT_betaretroviridae/RT_cavemovirus/RT_caulimovirus/RT_soymovirus/RT_tat/RT_gammaretroviridae/
RT_TF/RT_spumaretroviridae/RT_csrn1/RT_b_clade/RT_a_clade/RT_epsilonretroviridae/RT_galadriel/RT_v_clade/RT_gmr1/RT_gypsy/RT_osvaldo/RT_maggy/RT_del/RT_17_6/RT_412_mdg1/RT_micropia_mdg3/RT_crm/RT_pyggy/RT_athila/RT_reina/RT_pyret/RT_badnavirus/RNaseH_csrn1/RNaseH_b_clade/RNaseH_caulimovirus/RNaseH_maggy/RNaseH_reina/RNaseH_del/RNaseH_athila/RNaseH_crm/RNaseH_galadriel/RNaseH_osvaldo/RNaseH_pyggy/RNaseH_TF/RNaseH_pyret/RNaseH_v_clade/RNaseH_gmr1/RNaseH_a_clade/RNaseH_17_6/RNaseH_gypsy/RNaseH_micropia_mdg3/INT_csrn1/INT_b_clade/INT_athila/INT_epsilonretroviridae/INT_pyggy/INT_pyret/INT_maggy/INT_micropia_mdg3/INT_tat/INT_spumaretroviridae/INT_gmr1/INT_osvaldo/INT_cer2_3/INT_412_mdg1/INT_gammaretroviridae/INT_v_clade/INT_crm/INT_TF/INT_reina


B文件
GAG/AP/RT/RNaseH/INT        Gypsy
GAG/AP/INT/RT/RNaseH        Copia
GAG/AP/RT/INT/RNaseH        Bel




C文件
Chr01_9654239_9660689        645 Copia    ###包含GAG_copia/AP_copia/INT_copia/RT_copia/RNaseH_copia,满足GAG/AP/INT/RT/RNaseH的顺序
Chr01_13549455_13553995        4541 Copia  ###包含GAG_oryco/AP_oryco/INT_oryco/RT_oryco/RNaseH_oryco,满足GAG/AP/INT/RT/RNaseH的顺序
Chr01_13578874_13583841        4968 Copia  ###包含GAG_retrofit/AP_retrofit/INT_retrofit/RT_retrofit/RNaseH_retrofit,满足GAG/AP/INT/RT/RNaseH的顺序
Chr01_13708617_13713687        5071        Gypsy  ###包含GAG_reina/AP_reina/RT_reina/RNaseH_reina/INT_reina(满足GAG/AP/RT/RNaseH/INT的顺序GAG_del/AP_del/INT_del/RT_del/RNaseH_del(满足GAG/AP/INT/RT/RNaseH的顺序),但是GAG_reina在前,即为Gypsy


请教:如何根据B文件将A文件处理得到C文件?

论坛徽章:
8
2016科比退役纪念章
日期:2018-10-24 08:24:0115-16赛季CBA联赛之北控
日期:2019-03-12 14:34:562016科比退役纪念章
日期:2019-04-01 10:33:0915-16赛季CBA联赛之山东
日期:2019-04-17 12:46:3215-16赛季CBA联赛之广夏
日期:2019-05-09 16:40:4015-16赛季CBA联赛之广夏
日期:2019-10-10 15:33:4015-16赛季CBA联赛之辽宁
日期:2019-10-15 08:37:0615-16赛季CBA联赛之北控
日期:2021-03-30 15:53:34
发表于 2019-02-17 14:49 |显示全部楼层
本帖最后由 cfwyy 于 2019-02-27 16:42 编辑

楼主这个文本处理也不能说非常复杂,但光看懂题目就费了不少劲,再想想算法,写再调试着实花了不少时间,还好最近比较空,楼主是不是该给个大红包啊 哇哈哈: 先上awk 脚本 test.awk
  1. FILENAME=="B.txt"{
  2.     B2[NR]=$2     #保存B的第二列
  3.     BRow=NR
  4.     #保存关键字到二维数组
  5.     split($1,rowKey,"/")
  6.     for (i=1;i<=length(rowKey);i++)
  7.         allKey[NR,i]=rowKey[i]
  8. }
  9. FILENAME=="A.txt"{
  10.     #统计后缀,找到相同的后缀
  11.     split($3,suffixArr,"/")
  12.     for (i=1;i<=length(suffixArr);i++){
  13.         sub(/[A-Za-z]+?_/,"",suffixArr[i])   #去第一个_之前的 前缀,留后缀
  14.         numOfSuffix[suffixArr[i]]++          #每个后缀计数
  15.     }
  16.     for (suf in numOfSuffix){                #理论上for (i in Arr)顺序是随机的按awk版本不同实现顺序可能会不同,gawk的顺序没问题就偷下懒了。
  17.         if (numOfSuffix[suf]==5){            #找出第一个有5个相同的后缀(B中需要匹配的关键字个数都为5)
  18.             suffix=suf
  19.             break   
  20.         }
  21.     }
  22.     #清数组
  23.     delete suffixArr
  24.     delete numOfSuffix

  25.     if (!suffix)                            #没有找到满足条件的后缀,awk读下一行
  26.         next
  27.    
  28.     # 用 Bkey_Asuffix 去 匹配A的第3列
  29.     for (i=1;i<=BRow;i++){
  30.         isMatch=1
  31.         for (j=1;j<=5;j++){
  32.             idx[j]=match($3,allKey[i,j]"_"suffix)         #match()返回匹配的索引
  33.             if (j==1 && idx[j]>0)                         #第一个Bkey_Asuffix能匹配到
  34.                 continue
  35.             else if (j>=1 && idx[j]>0 && idx[j]>idx[j-1]) #之后能按顺序匹配到
  36.                 continue
  37.             else {
  38.                 isMatch=0
  39.                 break                                     #没匹配到或没按匹配顺序 ,则退出该行的匹配
  40.             }
  41.         }
  42.         if (isMatch){
  43.             matchRow=i
  44.             print $1,$2,B2[matchRow]                      #打印结果
  45.             break
  46.         }
  47.     }        
  48. }
复制代码
运行:
  1. awk -f test.awk B.txt A.txt >C.txt
复制代码


楼主给的数据测试通过。


论坛徽章:
0
发表于 2019-02-17 18:21 |显示全部楼层
本帖最后由 jzsjm1002 于 2019-02-17 20:59 编辑

整体思路是根据正则匹配 替换
楼主 A文件的数据量太少
GAG_reina在前,即为Gypsy 没有给出其他条件 是特定 _del的嘛
测试发现 A文件里第3列有空格 需要替换掉 楼主需要自行替换或者用sed vim等
  1. #!/bin/bash
  2. #

  3. path1=/mnt/a
  4. path2=/mnt/b
  5. count=`grep -c "" $path2`
  6. a1=(`sed -r 's#([^/]*)(/)#\1_.+\2.*#g;s/[[:space:]]+/:/;s/:/_.+.*&/' $path2`)
  7. #生成a1数组 并重组字符串成正则表达式

  8. for x in `seq 0 $(($count-1))`;do
  9. awk --re-interval -v a1=${a1[$x]} '
  10. function pr1(p1,p2,p3,p4,p5,   z){
  11. if(p5){
  12.   if($3~/(.*\/[^/]+_del\/?.*){5}/){
  13.    z=gensub(/.*\/([^/]+_del\/).*\/([^/]+_del\/).*\/([^/]+_del\/).*\/([^/]+_del\/).*\/([^/]+_del)\/?.*/,"\\1\\2\\3\\4\\5","1",$3)
  14. #匹配成功 并替换字符串 赋值给z
  15.    print p1,p2,p3"\n"p4"\n"z
  16.   }
  17.   else
  18.    print p1,p2,p3"\n"p4"\n"
  19. }
  20. else
  21.   printf("%s %d %s\n%s\n",p1,p2,p3,p4)
  22. }
  23. #定义一个pr1函数 来做打印 当匹配到reina字符串 进行判断

  24. BEGIN{split(a1,a,":")}{
  25. if($3~a[1]){
  26.   r=0                                    #每一行都将 r设置为0 当匹配到reina时 =1
  27.   split($3,b,"/")                        #将第3列切成数组
  28.   for(c in b){                           #下标循环
  29.    d=gensub(/[^_]+_(.+)/,"\\1","1",b[c]) #字符串替换 例reina del galadriel...
  30.    e=gensub(/\.\+/,d,"g",a[1])           #将下标进行字符串重组成正则   
  31.    if($3~e) f[e]++                       #匹配成功 数组f[e] +1
  32.    if(f[e]==5){                          #当f[e]=5
  33.     g=gensub(/\.\*/,"","g",e)            #将.*替换成为空
  34.     if(match(g,"reina")) r=1             #匹配reina 匹配成功 r=1
  35.     if(match(g,"del"))                   #匹配del 匹配r=0 跳出循环
  36.      if(r==0) continue   
  37.     print pr1($1,$2,a[2],g,r)            #调用pr1函数
  38.     f[e]=0
  39.    }
  40.   }
  41. }
  42. }' $path1
  43. done

  44. #在a1数组里做循环 例 GAG_.+/.*AP_.+/.*RT_.+/.*RNaseH_.+/.*INT_.+.*:Gypsy
复制代码

  1. root@vh10:/mnt# ./test.sh
  2. Chr01_13708617_13713687 5071 Gypsy
  3. GAG_reina/AP_reina/RT_reina/RNaseH_reina/INT_reina
  4. GAG_del/AP_del/INT_del/RT_del/RNaseH_del

  5. Chr01_9654239_9660689 645 Copia
  6. GAG_copia/AP_copia/INT_copia/RT_copia/RNaseH_copia

  7. Chr01_13549455_13553995 4541 Copia
  8. GAG_oryco/AP_oryco/INT_oryco/RT_oryco/RNaseH_oryco

  9. Chr01_13578874_13583841 4968 Copia
  10. GAG_retrofit/AP_retrofit/INT_retrofit/RT_retrofit/RNaseH_retrofit

  11. #执行结果
复制代码




论坛徽章:
0
发表于 2019-02-27 08:43 |显示全部楼层
回复 2# cfwyy

如果B文件需要匹配的个数有5个,也有6个呢

论坛徽章:
0
发表于 2019-02-27 10:19 |显示全部楼层
回复 2# cfwyy


不好意思,没有个数的问题。


我使用的awk 是4.01版本的。

我发现输入文件是这样的格式
Chr01_9654239_9660689   645     GAG_copia/GAG_tork/AP_copia/INT_tat/INT_17_6/INT_codi_d/INT_retrofit/INT_copia/INT_sire/INT_1731/INT_oryco/RT_hydra/RT_pCretro/RT_copia/RNaseH_codi_c


结果也会输出
Chr01_9654239_9660689   645  Copia

麻烦了。问题解决后应该有个红包的

论坛徽章:
0
发表于 2019-02-27 10:39 |显示全部楼层
回复 3# jzsjm1002


数据太多没办法粘贴,我以附件上传了。


A文件中第三列以/分割,GAG_XXX,AP_XXX, RT_XXX 等形式存在。

我的目的是下划线之后的XXX相同时,下划线之前的XXX满足B文件中第一列的顺序 的行提出来得到 C文件。
(形式:Chr01_9654239_9660689        645 Copia







ath_ltrdigest_tabout.rar

31.97 KB, 下载次数: 7

论坛徽章:
8
2016科比退役纪念章
日期:2018-10-24 08:24:0115-16赛季CBA联赛之北控
日期:2019-03-12 14:34:562016科比退役纪念章
日期:2019-04-01 10:33:0915-16赛季CBA联赛之山东
日期:2019-04-17 12:46:3215-16赛季CBA联赛之广夏
日期:2019-05-09 16:40:4015-16赛季CBA联赛之广夏
日期:2019-10-10 15:33:4015-16赛季CBA联赛之辽宁
日期:2019-10-15 08:37:0615-16赛季CBA联赛之北控
日期:2021-03-30 15:53:34
发表于 2019-02-27 16:45 |显示全部楼层
回复 5# wd_my

已更新,你再试试。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP