Awk 当行ID匹配时,如果子字符串中存在来自另一个文件的两个字符位置,则从文件中提取子字符串
我有一个带有标识符(ID)和两个位置号的文件。在真实文件中有12列,相关位置在字段7和8中,但是为了清楚起见,我从示例文件1中删除了该信息: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
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如何出现多次
$ 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,因此给出了错误的输出。我也意识到我没有正确地解释我的问题并给出所有参数,对此我感到抱歉,并感谢您的时间和知识。我编辑了我的问题。