bash:按模式、空字段和多次出现提取子串

bash: extraction of substrings by pattern, empty fields and multiple occurrences

我想从文件的每一行中提取 Pfam_A 信息:

item_1    ID=HJNANFJJ_180142;inference=ab initio prediction:Prodigal_v2.6.3;locus_tag=HJNANFJJ_180142;partial=01;product=unannotated protein;KEGG=K03531
item_4    ID=HJNANFJJ_87662;inference=ab initio prediction:Prodigal_v2.6.3;locus_tag=HJNANFJJ_87662;partial=10;product=unannotated protein;KEGG=K15725;Pfam_A=OEP;Resfams=adeC-adeK-oprM
item_8    ID=HJNANFJJ_328505;inference=ab initio prediction:Prodigal_v2.6.3;locus_tag=HJNANFJJ_328505;partial=11;product=unannotated protein;KEGG=K03578;Pfam_A=OB_NTP_bind    
item_2    ID=HJNANFJJ_512995;inference=ab initio prediction:Prodigal_v2.6.3;locus_tag=HJNANFJJ_512995;partial=11;product=unannotated protein;KEGG=K00674;Pfam_A=Hexapep;Pfam_A=Hexapep_2;metacyc=TETHYDPICSUCC-RXN
item_0    ID=HJNANFJJ_188729;inference=ab initio prediction:Prodigal_v2.6.3;locus_tag=HJNANFJJ_188729;partial=11;product=unannotated protein

在某些行中此信息根本缺失,在某些行中可能会多次出现。

最后,我想得到一个像这样的 table,这样 NaN 就不会出现空字段,而且多次出现的情况会被制表符分隔到不同的字段中:

item_1    NaN
item_4    OEP
item_8    OB_NTP_bind    
item_2    Hexapep    Hexapep_2
item_0    NaN

一种快速而肮脏的方法是:

awk '{ s=[=10=];t="";
    while (match(s,"Pfam_A=[^;]*")) {
       t = t (t?OFS:"") substr(s,RSTART+7,RLENGTH-7);
       s = substr(s,RSTART+RLENGTH)
    }
}{print , (t?t:"NaN")}' file

您可以使用这个 awk:

awk -v OFS='\t' 'NF > 1 {
   s = ""
   n = split($NF, a, /;/)
   for (i=1; i<=n; i++)
      if (split(a[i], b, /=/) == 2 && b[1] == "Pfam_A")
         s = s OFS b[2]
   print  (s ? s : OFS "NaN")
}' file
item_1  NaN
item_4  OEP
item_8  OB_NTP_bind
item_2  Hexapep Hexapep_2
item_0  NaN

假设在每个输入行中,除了分隔数据字段的 ; 字符之外没有其他 ; 字符,并且没有制表符,除非它们分隔第一列,一个简单的 sed 命令就可以完成这项工作:

sed -E 's/\s+/;/; s/;Pfam_A=/;\t/g; s/;[^\t]*//g; /\t/!s/$/\tNaN/' file