perl - 从文件中排除某些行

时间:2016-01-13 13:06:48

标签: perl

我写了一个简短的脚本来转换我的数据(从输入文件到输出)。我停下来,当我只能用负能量(每行中的最后一个值)提取这些线时。

我的输入数据是:

ATOM    367  OH2 HOH   367      -2.010   7.370  -7.369   -6.52
ATOM    491  OH2 HOH   491       0.990   8.370  -8.369   -2.24
ATOM    652  OH2 HOH   652       5.490  -6.130   2.631    2.98
ATOM    689  OH2 HOH   689       6.490 -15.130   8.631   -4.23
ATOM    738  OH2 HOH   738       7.490  19.870  -8.369    3.38
ATOM    793  OH2 HOH   793       8.990  -2.630 -22.869   -2.29
ATOM    857  OH2 HOH   857      10.490  13.370  -5.869   -1.31
.
.
.

我的输出数据如下:

    moja woda t=   0 
        1
        1SOL     OW    1  -0.344   0.437   0.633  -9.290
     20.0 20.0 20.0
    moja woda t=   1 
        1
        1SOL     OW    1  -0.194   0.537  -0.767  -2.990
     20.0 20.0 20.0
    moja woda t=   2 
        1
        1SOL     OW    1  -0.044   0.287   0.333   4.960
     20.0 20.0 20.0
    moja woda t=   3 
        1
        1SOL     OW    1   0.106   0.837  -0.817  -1.300
     20.0 20.0 20.0
    moja woda t=   4 
    .
    .
    .

我的脚本是:

!/usr/bin/perl -w

use strict;

my $list=$ARGV[0];


open(LST,$list) or die;

my $time=0;

my @id_table;
my @nr_table;

open(GRO,">waters.gro") or die;

while(<LST>) {
  my $pdb_file=$_;
  chomp $pdb_file;
  my $pdb_id=substr $pdb_file,0,4;
  open(PDB,$pdb_file) or die;
  while(<PDB>) {
      my $line=$_;
      my $x=substr $line,30,8;
      my $y=substr $line,38,8;
      my $z=substr $line,46,8;
      my $en=substr $line,54,8;
      my $w_id=substr $line,23,3;
      print GRO "moja woda t=   $time \n";
      printf(GRO "%5d\n",1);
      printf(GRO "    1SOL     OW    1%8.3f%8.3f%8.3f%8.3f\n",$x/10.0,$y/10.0,$z/10.0,$en);
      print GRO " 20.0 20.0 20.0\n";
      $id_table[$time]=$pdb_id;
      $nr_table[$time]=$w_id;
      $time++;
  }
  close PDB;
}
close GRO;

我只想转换能量值小于0(最后一列)的这些线。我究竟应该怎么做?

提前谢谢你, 微米。

2 个答案:

答案 0 :(得分:2)

好的,对于初学者 - 不要使用 chart.addSeries({ id : 'mean', name : 'mean', type : 'line', lineWidth : 1, lineColor : 'rgba(0,128,0,0.9)', color : 'rgba(0,128,0,0.9)', dashStyle : 'LongDash', zIndex : 5, data : [[ext.dataMin, mean], [ext.dataMax, mean]], enableMouseTracking: false }); 这个,这是令人讨厌的。试试substr

然后你就可以测试&#39;字段值。这是一个减少的例子:

split

注意 - 默认情况下,#!/usr/bin/env perl use strict; use warnings; my @nr_table; my @id_table; while ( <DATA> ) { my @fields = split; my ( $pdb_id, $w_id ) = @fields[0,1]; if ( $fields[8] < 0 ) { print "moja woda t= ",scalar @id_table, "\n"; printf( "%5d\n",1); printf( " 1SOL OW 1%8.3f%8.3f%8.3f%8.3f\n", map { $_ / 10.0 } @fields[5..7], $fields[8]); print " 20.0 20.0 20.0\n"; } push ( @id_table, $pdb_id ); push ( @nr_table, $w_id ); } __DATA__ ATOM 367 OH2 HOH 367 -2.010 7.370 -7.369 -6.52 ATOM 491 OH2 HOH 491 0.990 8.370 -8.369 -2.24 ATOM 652 OH2 HOH 652 5.490 -6.130 2.631 2.98 ATOM 689 OH2 HOH 689 6.490 -15.130 8.631 -4.23 ATOM 738 OH2 HOH 738 7.490 19.870 -8.369 3.38 ATOM 793 OH2 HOH 793 8.990 -2.630 -22.869 -2.29 ATOM 857 OH2 HOH 857 10.490 13.370 -5.869 -1.31 会对split - 当前行进行操作,并在&#39;任何空格&#39;上进行分割。

如果需要,您可以在条件内移动$_语句。

答案 1 :(得分:0)

我不会尝试根据字符串中的特定位置提取值,而是使用split函数将每一行拆分为一个数组。

替换这个:

my $x=substr $line,30,8;
my $y=substr $line,38,8;
my $z=substr $line,46,8;
my $en=substr $line,54,8;
my $w_id=substr $line,23,3;

用这个:

my ($w_id, $x, $y, $z, $en) = (split(/\s+/, $line))[1, 5, 6, 7, 8];
next if $en >= 0;

这应该足以获得你想要的输出。

它在做什么?

my @array = split(/\s+/, $line)告诉perl将字符串拆分为一个列表。 /\s+/是一个正则表达式,它告诉split函数分割一个或多个空白字符。

@array将包含9个entires,每个数据列一个。由于您没有使用所有列,因此我使用数组切片仅提取您感兴趣的条目。例如,my ($zero, $one, $three) = (@array)[0, 1, 3]提取@array的索引0,1和3处的元素并将它们放入变量中$零,$ 1和$ 3。

next if $en > 0;行告诉脚本如果$en的值为正,则跳过循环当前迭代的其余部分。