Perl:匹配四个不同的文件并在输出文件中获取特定信息

时间:2012-06-05 23:45:49

标签: perl

我有四个文件。文件1(名为inupt_22.txt)是一个包含两列(空格分隔)的输入文件。第一列是按字母顺序排序的配体代码列表(特定配体的三个字母/数字代码)。第二列是各个配体代码(未分类列表)的PDBcodes(蛋白质数据库代码)列表。enter image description here

文件1(input_22.txt):

    803      1cqp    
    AMH      1b2i    
    ASC      1f9g    
    ETS      1cil    
    MIT      1dwc    
    TFP      1ctr     
    VDX      1db1     
    ZMR      1a4g      

文件2(命名为SD_2.txt)是每个配体片段的SDF(结构数据文件)。配体可含有一个或多于一个片段。例如,这里803是配体代码,它有两个片段。所以文件看起来像:4美元符号($$$$),然后是下一行中的配体代码(即本例中为803)。每个片段都遵循同样的事情。接下来,在每个片段的第5行(来自$$$$.\n803的第三行)中,有一个数字表示下一行行中的行数,如第一个片段中的7个和803个配体的下一个片段中的10个。现在,下一行行包含一列(61-62),其中包含引用片段中原子的特定数字。例如,在803的第一个片段中,这些数字是15,16,17,19,20,21,22。这些数字需要在文件3中匹配。enter image description here

文件2(SD_2.txt)如下所示:

$$$$    
803    
  SciTegic05101215222D    


  7  7  0  0  0  0            999 V2000    
    3.0215   -0.5775    0.0000 C   0  0  0  0  0  0  0  0  0 15  0  0     
    2.3070   -0.9900    0.0000 C   0  0  0  0  0  0  0  0  0 16  0  0     
    1.5926   -0.5775    0.0000 C   0  0  0  0  0  0  0  0  0 17  0  0      
    1.5926    0.2475    0.0000 C   0  0  0  0  0  0  0  0  0 19  0  0      
    2.3070    0.6600    0.0000 C   0  0  0  0  0  0  0  0  0 20  0  0      
    2.3070    1.4850    0.0000 O   0  0  0  0  0  0  0  0  0 21  0  0      
    3.0215    0.2475    0.0000 O   0  0  0  0  0  0  0  0  0 22  0  0      
  1  2  1  0      
  1  7  1  0       
  2  3  1  0     
  3  4  1  0      
  4  5  1  0      
  5  6  2  0     
  5  7  1  0      
M  END      
> <Name>      
803      

> <Num_Rings>      
1      

> <Num_CSP3>       
4     

> <Fsp3>       
0.8         

> <Fstereo>       
0      

$$$$      
803       
  SciTegic05101215222D       

 10 11  0  0  0  0            999 V2000       
   -1.7992    -1.7457    0.0000 C   0  0  0  0  0  0  0  0  0  1  0  0        
   -2.5137    -1.3332    0.0000 C   0  0  0  0  0  0  0  0  0  2  0  0        
   -2.5137    -0.5082    0.0000 C   0  0  0  0  0  0  0  0  0  3  0  0        
   -1.7992    -0.0957    0.0000 C   0  0  0  0  0  0  0  0  0  5  0  0        
   -1.0847   -0.5082    0.0000 C   0  0  0  0  0  0  0  0  0  6  0  0       
   -0.3702    -0.0957    0.0000 C   0  0  0  0  0  0  0  0  0  7  0  0        
    0.3442     -0.5082    0.0000 C   0  0  0  0  0  0  0  0  0  8  0  0       
    0.3442     -1.3332    0.0000 C   0  0  0  0  0  0  0  0  0  9  0  0        
   -0.3702     -1.7457    0.0000 C   0  0  0  0  0  0  0  0  0 11  0  0      
   -1.0847    -1.3332    0.0000 C   0  0  0  0  0  0  0  0  0 12  0  0       
  1  2  1  0        
  1 10  1  0      
  2  3  1  0      
  3  4  1  0      
  4  5  2  0      
  5  6  1  0      
  5 10  1  0     
  6  7  2  0      
  7  8  1  0      
  8  9  1  0     
 10  9  1  0      
M  END        
> <Name>       
803       

> <Num_Rings>     
2     

> <Num_CSP3>     
6     

> <Fsp3>     
0.6      

> <Fstereo>      
0.1      

文件3是CIF(晶体信息文件)。该文件可从以下链接获得:File_3 该文件是几个配体分子的单个cif文件的集合。文件中的每个部分都以data_ligandcode开头。对于我们的示例,它将是data_803。从收集的每个小文件开始46行后,有一个块提供有关分子的结构信息。此块中的行数不固定。但是,此块以哈希符号(#)结束。在这个区块中,两列是重要的,分别是53-56和62-63。 62-63列包含可以从文件2中获得的数字匹配的数字。并且,53-56包含像C1 (Carbon 1)等原子名称。此列可用于与文件4匹配。

文件4是Grow.out文件,其中包含有关每种配体与其靶蛋白相互作用的信息。文件名是文件1中针对每个配体给出的PDBcode。例如,对于配体803,PDBcode是1cqp。因此,grow.out文件的名称为1cqp。 1cqp 在这个文件中,那些包含配体代码的行很重要(例如803)和从文件3的53-56列获得的原子名称。

任务:我需要一个从文件1读取配体代码的脚本,转到文件2搜索$$$$ . \nLigandcode,然后从列61-62获取每个片段的数字。然后在下一步中,我的脚本应将这些数字传递给文件3,并匹配文件3的第62-63行中包含这些数字的行,然后提取第53-56列(原子名称)中的信息。最后一步是打开文件4,名称为PDBcode,然后打印包含配体代码的行和从文件3中获取的原子名称。打印应在输出文件中完成。

我是生物医学研究生。我没有计算机科学背景。但是,我必须使用Perl编程来完成某些任务。对于上面提到的任务,我写了一个脚本,但它工作不正常,我找不到它背后的原因。我写的脚本是:

#!/usr/bin/perl
use strict;
use warnings;
use Text::Table;
use Carp qw(croak);

{

    my $a;
    my $b;
    my $input_file = "input_22.txt";
    my @lines = slurp($input_file);
    for my $line (@lines){
        my ($ligandcode, $pdbcode) = split(/\t/, $line);
        my $i=0;
        my $k=0;

        my @array;
        my @array1;

        open (FILE, '<', "SD_2.txt");


        while (<FILE>) {
            my $i=0;
            my $k=0;

            my @array;
            my @array1;

            if ( $_=~/\x24\x24\x24\x24/ . /\n$ligandcode/) {


                my $nextline1 = <FILE>;
                my $nextline2 = <FILE>;
                my $nextline3 = <FILE>;
                my $nextline4= <FILE>;

                my $totalatoms= substr( $nextline4, 1,2);
                print $totalatoms,"\n";
                while ($i<$totalatoms)
                  {

                      my $nextlines= <FILE>;

                      my $sub= substr($nextlines, 61, 2);
                      print $sub;
                      $array[$i] = $sub;
                      open (FH, '<', "components.txt");

                      while (my $ship=<FH>) {
                          my $var="data_$ligandcode";
                          if ($ship=~/$var/)


                            {

                                while ($k<=44)
                                  {
                                      $k++;
                                      my $nextline = <FH>;

                                  }

                                my $j=0;
                                my $nextline3;
                                do
                                  {

                                      $nextline3=<FH>;
                                      print $nextline3;

                                      my $part= substr($nextline3, 62, 2);
                                      my $part2= substr($nextline3, 53, 4);
                                      $array1[$j] = $part;
                                      if ($array1[$j] eq $array[$i])
                                        {
                                            print $part2, "\n";
                                            open (GH, '<', "$pdbcode"); 
                                            open (OH, ">>out_grow.txt");
                                            while (my $grow = <GH>)
                                              {
                                                  if ( $grow=~/$ligandcode/){
                                                      print OH $grow if $grow=~/$part2/; 
                                                  }}
                                            close (GH);
                                            close (OH);
                                        }

                                      $j++;
                                  } while $nextline3 !~/\x23/;
                            }
                      }
                      $i++;
                      close (FH);
                  }

            }}

        close (FILE);

    }
}


##Slurps a file into a list
sub slurp {
    my ($file) = @_;
    my (@data, @data_chomped);
    open IN, "<", $file or croak "can't open $file\n";
    @data = <IN>;
    for my $line (@data){
        chomp($line);
        push (@data_chomped, $line);
    }
    close IN;
    return (@data_chomped);
}

如果我在文件1中列出400个分子,我想让它成为一个快速运行的脚本并完全适用于1000个片段。请帮助我使这个脚本正常工作。我将不胜感激。

1 个答案:

答案 0 :(得分:1)

您需要将代码分解为可管理的步骤。

  1. 从文件

    创建数据结构
    use Slurp;
    
    my @input = map{
      [ split /\s+/, $_, 2 ]
    } slurp $input_filename;
    
    # etc
    
  2. 使用这些数据结构处理input_22.txt的每个元素。

  3. 我真的认为你应该研究PerlMol。毕竟,使用Perl的一半原因是CPAN


    你做得很好的事情

    • 使用3-arg open
    • use strict;
    • use warnings;

    你不应该做的事情

    • (重新)定义了$a$b
      它们已经为您定义了。
    • 重新实现slurp(很差)
    • 多次读取同一文件 您为SD_2.txt的每一行开了一次input_22.txt
    • 在您使用它们的范围之外定义的符号 $j$k@array@array1定义了两次,但只使用了其中一个定义。
    • 使用openclose时没有进行某种错误检查 open ... or die;use autodie;
    • 您使用了裸字文件句柄。 INFILE等 而是使用open my $FH, ...

    对于一次性的计划,其中大部分都没有那么重要。