我有一个包含两列的数据集:


十进制数
一长串


我想从第二列中提取每个FBtr编号(例如FBtr0072798),而忽略其余的。

 0.850359 EFF=INTRON(MODIFIER|||||drpr|||FBtr0072798|4|1),INTRON(MODIFIER|||||drpr|||FBtr0072799|4|1),INTRON(MODIFIER|||||drpr|||FBtr0309845|4|1),SYNONYMOUS_CODING(LOW|SILENT|atT/atA|I690||CG18171|||FBtr0072800|1|1)
 0.473555 EFF=INTRON(MODIFIER|||||drpr|||FBtr0072798|4|1),INTRON(MODIFIER|||||drpr|||FBtr0072799|4|1),INTRON(MODIFIER|||||drpr|||FBtr0309845|4|1),SYNONYMOUS_CODING(LOW|SILENT|agC/agT|S371||CG18171|||FBtr0072800|1|1),UPSTREAM(MODIFIER|||||CG12035|||FBtr0072766||1)
 0.969735 EFF=INTRON(MODIFIER|||||drpr|||FBtr0072798|4|1),INTRON(MODIFIER|||||drpr|||FBtr0072799|4|1),INTRON(MODIFIER|||||drpr|||FBtr0309845|4|1),SYNONYMOUS_CODING(LOW|SILENT|gtT/gtC|V366||CG18171|||FBtr0072800|1|1),UPSTREAM(MODIFIER|||||CG12035|||FBtr0072766||1)


我最终希望将其转置为长格式,以便每一行都包含第一列中的十进制数字,并与单个FBtr数字配对。例如。,

 0.850359   FBtr0072798
 0.850359   FBtr0072799
 0.850359   FBtr0309845
 0.850359   FBtr0072800
 0.473555   FBtr0072798
 0.473555   FBtr0072799
 0.473555   FBtr0309845
 0.473555   FBtr0072800
 0.473555   FBtr0072766
 0.969735   FBtr0072798
 0.969735   FBtr0072799
 0.969735   FBtr0309845
 0.969735   FBtr0072800
 0.969735   FBtr0072766


我一直在尝试逐步进行此操作,首先将FBtr编号提取到单独的列中:

 0.850359   FBtr0072798 FBtr0072799 FBtr0309845 FBtr0072800
 0.473555   FBtr0072798 FBtr0072799 FBtr0309845 FBtr0072800 FBtr0072766
 0.969735   FBtr0072798 FBtr0072799 FBtr0309845 FBtr0072800 FBtr0072766


然后从宽格式转换为长格式。

现在,我在提取FBtr编号时遇到问题。我比unix在python方面的新手更多,所以我一直在尝试使用unix,因为我对语言更满意。到目前为止,我尝试过的最有希望的事情是使用sed来重复查找/替换每个术语。

 sed -e 's/\(.* \).*\(FBtr[0-9]*\).*\(FBtr[0-9]*\).*\(FBtr[0-9]*\).*\(FBtr[0-9]*\).*\(FBtr[0-9]*\).*/ \1 \2 \3 \4 \5 \6/ g' file.txt


这不仅在所有重复中都是丑陋的,而且仅当行中出现相同数量的FBtr时才有用,但不幸的是没有。关于如何在Unix或python中解决此问题的任何想法?

最佳答案

这是我认为符合您要求的小python程序。它使用str.split()str.startswith()查找所有以FBtr开头的字符串。

码:

for line in test_data:
    num, string = line.split(' ', 1)
    for field in string.split('|'):
        if field.startswith('FBtr'):
            print(num, field)


测试数据:

test_data = [x.strip() for x in """
    0.850359 EFF=INTRON(MODIFIER|||||drpr|||FBtr0072798|4|1),INTRON(MODIFIER|||||drpr|||FBtr0072799|4|1),INTRON(MODIFIER|||||drpr|||FBtr0309845|4|1),SYNONYMOUS_CODING(LOW|SILENT|atT/atA|I690||CG18171|||FBtr0072800|1|1)
    0.473555 EFF=INTRON(MODIFIER|||||drpr|||FBtr0072798|4|1),INTRON(MODIFIER|||||drpr|||FBtr0072799|4|1),INTRON(MODIFIER|||||drpr|||FBtr0309845|4|1),SYNONYMOUS_CODING(LOW|SILENT|agC/agT|S371||CG18171|||FBtr0072800|1|1),UPSTREAM(MODIFIER|||||CG12035|||FBtr0072766||1)
    0.969735 EFF=INTRON(MODIFIER|||||drpr|||FBtr0072798|4|1),INTRON(MODIFIER|||||drpr|||FBtr0072799|4|1),INTRON(MODIFIER|||||drpr|||FBtr0309845|4|1),SYNONYMOUS_CODING(LOW|SILENT|gtT/gtC|V366||CG18171|||FBtr0072800|1|1),UPSTREAM(MODIFIER|||||CG12035|||FBtr0072766||1)
""".split('\n')[1:-1]]


给出输出:

0.850359 FBtr0072798
0.850359 FBtr0072799
0.850359 FBtr0309845
0.850359 FBtr0072800
0.473555 FBtr0072798
0.473555 FBtr0072799
0.473555 FBtr0309845
0.473555 FBtr0072800
0.473555 FBtr0072766
0.969735 FBtr0072798
0.969735 FBtr0072799
0.969735 FBtr0309845
0.969735 FBtr0072800
0.969735 FBtr0072766

10-01 15:12