Awk 当行ID匹配时,如果子字符串中存在来自另一个文件的两个字符位置,则从文件中提取子字符串

Awk 当行ID匹配时,如果子字符串中存在来自另一个文件的两个字符位置,则从文件中提取子字符串,awk,Awk,我有一个带有标识符(ID)和两个位置号的文件。在真实文件中有12列,相关位置在字段7和8中,但是为了清楚起见,我从示例文件1中删除了该信息: ID1 1 18 ID2 5 12 ID3 9 24 ID2 7 14 第二个文件包含我感兴趣的字符串。行具有与文件1中相同的标识。文件2: ID1 abcdefghijklmnopqr*stuvw**xyz ID2 ab*cdefghijklmno*pqrst*uvwxyz ID3 *abcd*efghi*j

我有一个带有标识符(ID)和两个位置号的文件。在真实文件中有12列,相关位置在字段7和8中,但是为了清楚起见,我从示例文件1中删除了该信息:

ID1   1   18
ID2   5   12
ID3   9   24
ID2   7   14
第二个文件包含我感兴趣的字符串。行具有与文件1中相同的标识。文件2:

ID1   abcdefghijklmnopqr*stuvw**xyz
ID2   ab*cdefghijklmno*pqrst*uvwxyz
ID3   *abcd*efghi*jklmnopqrs*tuvwxyz
ID4   abcde*fgh*ijklmnopq*rstuvwxyz*
此时,字段2中的字符串本身由星号(*)分隔为更小的子字符串。在这种情况下,子字符串定义为字段开头和星号之间、两个星号之间、星号和字段结尾之间或字段开头/结尾之间的任何字符串

我想做的是,如果文件之间的ID匹配以及file1中的两个位置对应于file2中相同子字符串中的字符,则将整个子字符串附加到file1,不包括星号。期望输出:

ID1   1   18   abcdefghijklmnopqr
ID2   5   12   cdefghijklmno
ID3   9   24   
ID2   7   14   cdefghijklmno
说明:

  • 对于ID1,字符串中的位置1对应于“a”,它也是子字符串的第一个字母。位置18对应于“r”,也是子字符串的最后一个字母,因此打印位置1-18就足够了
  • 然而,对于ID2的首次出现,字符串中的位置5对应于d,d不是子字符串的第一个字母。位置12也不是子字符串的最后一个字母(k位于位置12)。但是,整个子字符串(c到o)都应该打印出来
  • 对于ID3,位置9和24位于不同的子字符串中,因此不应打印子字符串
  • 对于第二次出现的ID2,与第一次出现的情况相同,提供此示例是为了说明一个ID如何出现多次
字符串可以以星号开始和/或结束,可以出现多个后续星号,并且字符串也可以完全没有星号。文件2中存在文件1中未出现的ID。File1每个ID可以包含多行,file2每个ID只能包含一行

我希望我把问题说清楚。我对这一点还很陌生,感谢你的帮助

$ cat tst.awk
NR==FNR {
    beg[$1] = $2
    end[$1] = $3
    next
}
{
    str = ""
    tgt = substr($2,beg[$1],end[$1]-beg[$1])
    if ( tgt !~ /[*]/ ) {
        bef = substr($2,1,beg[$1]-1)
        aft = substr($2,end[$1]+1)
        sub(/.*[*]/,"",bef)
        sub(/[*].*/,"",aft)
        str = bef tgt aft
    }
    print $1, beg[$1], end[$1], str
}

$ awk -f tst.awk file1 file2
ID1 1 18 abcdefghijklmnopq
ID2 5 12 cdefghijlmno
ID3 9 24

根据您更新的示例:

$ cat tst.awk
NR==FNR {
    map[$1] = $2
    next
}
{
    val = map[$1]
    beg = $2
    end = $3
    str = ""
    tgt = substr(val,beg,end-beg)
    if ( tgt !~ /[*]/ ) {
        bef = substr(val,1,beg-1)
        aft = substr(val,end+1)
        sub(/.*[*]/,"",bef)
        sub(/[*].*/,"",aft)
        str = bef tgt aft
    }
    print $1, beg, end, str
}

$ awk -f tst.awk file2 file1
ID1 1 18 abcdefghijklmnopq
ID2 5 12 cdefghijlmno
ID3 9 24
ID2 7 14 cdefghijklno

非常好的初学者Q和你自己做的格式!阅读
awk
match()
substr()
函数。祝你好运。嘿,谢谢你,Ed。这对我最初提供的示例有效,但是当适应我的文件时,脚本没有正确匹配ID,因此给出了错误的输出。我也意识到我没有正确地解释我的问题并给出所有参数,对此我感到抱歉,并感谢您的时间和知识。我编辑了我的问题。