我写了一个简短的脚本来转换我的数据(从输入文件到输出)。我停下来,当我只能用负能量(每行中的最后一个值)提取这些线时。
我的输入数据是:
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(最后一列)的这些线。我究竟应该怎么做?
提前谢谢你, 微米。
答案 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
的值为正,则跳过循环当前迭代的其余部分。