首页 > 解决方案 > 如何将每行的第一列数据添加到对应行中由某些特定字符串或字符标记的每列的头部?

问题描述

我有一大块数据(一个文件)如下,每行有不同数量的列(由制表符分隔),数据结构如下:

>NP_12345.1 matchnumber_1_RKHKK 
>NP_56789.2 matchnumber_1_HGRR  matchnumber_2_KQRHH  matchnumber_3_RVRK matchnumber_4_HTHH
>XP_543421.1    matchnumber_1_RQRH  ... matchnumber_m_RVRR
...

在上面的文件中,第 1 行有 2 列,第 2 行有 5 列,第 3 行有 m+1 列...;显然,文件的每一行都有“>accessionID”和“matchnumber_i_XXX”。我想将每一行的第一列添加到对应行中以“matchnumber”标记的每一列的头部,并打印为fasta格式,输出是这样的:

>NP_12345.1matchnumber_1
RKHKK   
>NP_56789.2matchnumber_1
HGRR    
>NP_56789.2matchnumber_2
KQRHH
>NP_56789.2matchnumber_3
RVRK
>NP_56789.2matchnumber_4
HTHH
>XP_543421.1matchnumber_1
RQRH
....
>XP_543421.1matchnumber_m
RVRR
...

任何人都可以帮助我吗?提前致谢。

注意:当有一行文件时,例如文件“a.txt”只有一行内容:

>NP_56789.2 matchnumber_1_HGRR  matchnumber_2_KQRHH  matchnumber_3_RVRK matchnumber_4_HTHH

我可以使用管道 awk 和 sed 命令来解析数据:

cat a.txt |awk -v OFS="\t" '{print $1$2,$1$3,$1$4,$1$5}' | sed 's/\t/\n/g' | sed 's/_/ /g' | sed 's/NP /NP_/g' | sed 's/matchnumber /matchnumber_/g' | sed 's/ /\n/g' > a.fasta

a.fasta 如下:

>NP_56789.2matchnumber_1
HGRR
>NP_56789.2matchnumber_2
KQRHH
>NP_56789.2matchnumber_3
RVRK
>NP_56789.2matchnumber_4
HTHH

当 a.txt 有多行该数据时,我不知道如何解决问题。

标签: pythonregexbashawksed

解决方案


$ cat jfile
>NP_12345.1     matchnumber_1_RKHKK
>NP_56789.2     matchnumber_1_HGRR      matchnumber_2_KQRHH     matchnumber_3_RVRK      matchnumber_4_HTHH

$ awk -F"\t" '{for(i=2;i<=NF;i++){match($i,"(matchnumber_[0-9]+)_(.*)",r);print $1 r[1] ORS r[2];}}' jfile
>NP_12345.1matchnumber_1
RKHKK
>NP_56789.2matchnumber_1
HGRR
>NP_56789.2matchnumber_2
KQRHH
>NP_56789.2matchnumber_3
RVRK
>NP_56789.2matchnumber_4
HTHH

从第二个字段循环$2到最后一个字段$NF,使用matchandregex取出你想要的东西,例如matchnumber_1RKHKK一个字段,然后打印。

在 awk 中,空格仅用于连接,ORS表示行结束,\n在这里实际上等于。r是正则表达式匹配的数组,其中r[0]代表整个匹配的字符串,r[1]和r[2]代表第一对和第二对()匹配的内容。-- 您可以更改r为您想要的其他变量名称。

至于正则表达式,[0-9] 表示任何单个数字,+其后表示匹配 1 个或多个前面表示的事物,这里表示 1 个或多个连续数字。如上所述,括号只是为了将内容捕获到组中,以供以后参考。每对括号匹配的内容都将保存到我提供的数组的一个元素中,即r此处。


推荐阅读