如何从文件中提取特定值并将其打印到另一个文件中

时间:2018-01-08 04:01:06

标签: bash perl

我有PDB文件,这些文件由其PDB ID命名,例如2KRJ.pdb。我想从它们中仅提取以ATOMHETATM开头的行,并将它们复制到具有相同名称和.txt扩展名的新文件中,例如{{1} }。

我知道如何提取这些行,但我无法将它们复制到另一个文件中。

这是我到目前为止提取的用于提取的脚本:

2KRJ.txt

问题是这个脚本不打印第一列,输出有点杂乱,每行没有四列。

我想要提取的行看起来像这样:

#!/usr/bin/perl -w

$dirname = '.';
opendir(DIR, $dirname) or die "cannot open directory";
@files = grep(/\.pdb$/,readdir(DIR));

foreach $files ( @files ) {

    open (FH, $files) or die "could not open $files\n";
    @file_each = <FH>;
    #print @file_each;
    #print "$file\n";
    close FH;

    #$dir_sz = scalar @files;
    #print "$dir_sz\n";
    close DIR;

    my @ac        = ();
    my @dr        = ();
    my @os        = ();
    my @names     = ();
    my @ion_names = ();
    my $flag      = 0;

    for ( my $line = 0; $line <= $#file_each; $line++ ) {  # loop reading each line from the @file up to the end of file  

        chomp( $file_each[$line] );

        if ( $file_each[$line] =~ /^HEADER/ ) {

            my @id       = split '\s+', $file_each[$line];
            my $filename = pop @id;
            $filename    = "$filename.pdb";

            while ( $file_each[$line] !~ /^END/ ) { # read the lines until you get the symbol 'END'

                $line++;

                if ( $file_each[$line] =~/^ATOM|^HETATM/ ) {

                    $file_each[$line] =~ s/^ATOM|^HETATM//;

                    @xyz = split '\s+', $file_each[$line];
                    chomp @xyz[0,6,7,8];
                    print join (':', @xyz), "\n";

                    push @coord, @xyz[0,6,7,8];
                    print "@coord\n";
                }

                open (OUTPUT, ">$filename.txt"); 
                print(OUTPUT "@coord\n"); 
                close OUTPUT;
            }
        }
    }
}

我正在尝试更改它,以便新文本文件脚本仅包含此内容:

ATOM    946  OH  TYR A  59      37.734  36.478  24.541  1.00  0.00           O  
ATOM    947  H   TYR A  59      33.478  35.320  18.896  1.00  0.00           H  

但我得到了这个

ATOM   37.734  36.478  24.541          
ATOM   33.478  35.320  18.896 

1 个答案:

答案 0 :(得分:1)

这将按照您的要求进行

你是否看到如何试图破解现有程序会导致你编写太多代码,从而增加错误的可能性?请学习用Perl编程并停止依赖慷慨灵魂的免费赠品

use strict;
use warnings 'all';
use autodie;

for my $pdb ( glob '*.pdb' ) {

    open my $fh, '<', $pdb;
    my $out_fh;

    while ( <$fh> ) {
        next unless my @fields = split;

        if ( $fields[0] eq 'HEADER' ) {
            open $out_fh, '>', "$fields[-1].txt";
        }
        elsif ( $fields[0] eq 'ATOM' or $fields[0] eq 'HETATM' ) {

            unless ( $out_fh ) {
                warn qq{No ID found for file "$pdb"};
                last;
            }

            print $out_fh "@fields[0,6,7,8]\n";
        }
    }
}

输出

ATOM 15.200 27.271 13.911
ATOM 15.336 27.312 15.415
ATOM 16.364 26.299 15.932
ATOM 16.167 25.081 15.787
ATOM 14.019 26.968 16.088
ATOM 14.198 27.038 17.607
ATOM 13.515 25.568 15.575
ATOM 14.524 28.415 18.088
ATOM 17.456 26.771 16.532
ATOM 18.424 25.815 17.028
ATOM 19.122 26.165 18.302
ATOM 19.066 27.314 18.764
...