我有一些pdb文件,我想只保留那些以^FORMUL
开头的行,如果行有C
后面跟着大于(C3,C4,C5,C6..100 etc
)的数字然后我不应该打印它。第二个条件是,C, H and N
中每一行的总和应为>=
6,然后将其删除
因此,请完全删除C
后面的数字超过2>
的数字,C+O+N
的总和为>=
,然后是6。
FORMUL 3 HOH *207(H2 O) (print it)
FORMUL 2 SF4 FE4 S4 (print it)
FORMUL 3 NIC C5 H7 N O7 (don't print, there is C5 and sum is more then 6)
FORMUL 4 HOH *321(H2 O) (print it)
FORMUL 3 HEM 2(C34 H32 FE N4 O4) (don't print, there is C34)
我曾尝试在perl
中进行此操作,但线条彼此之间存在太多差异,因此我不确定是否可以这样做。
在所有这些条件中,chould应包含在一起,这意味着应删除C>2
和sum>=6
的所有行。
应删除C1 O5 N3
; C3 N1 01
C
为3
后,不应删除#!/usr/bin/perl
use strict;
use warnings;
my @lines;
my $file;
my $line;
open ($file, '<', '5PCZ.pdb') or die $!;
while (my $line = <$file>)
{
if ($line =~ m/^FORMUL/)
{
push (@lines, $line);
}
}
close $file;
#print "@lines\n";
foreach $line(@lines)
{
if ($line eq /"C"(?=([0-2]))/ )
{
elsif ($line eq "Sum of O,N & C is lt 6")
print @lines
}
}
。
在perl中,我不知道如何分配这两个条件。在这里,我写了相反的情况,不删除,但如果不满足这两个条件,打印这些行。
ORDER BY
答案 0 :(得分:2)
扩展 Awk
解决方案:
awk -F'[[:space:]][[:space:]]+' \
'/^FORMUL/{
if ($4 !~ /\<C/) print;
else {
match($4, /\<C[0-9]+/);
c=substr($4, RSTART+1, RLENGTH);
if (c > 2) next;
else {
match($4, /\<O[0-9]+/);
o=substr($4, RSTART+1, RLENGTH);
match($4, /\<N[0-9]+/);
n=substr($4, RSTART+1, RLENGTH);
if (c+o+n < 6) print
}
}
}' 5PCZ.pdb
输出:
FORMUL 3 HOH *207(H2 O)
FORMUL 2 SF4 FE4 S4
FORMUL 4 HOH *321(H2 O)
答案 1 :(得分:2)
正如您所见,将其编写为打印您要保留的行的过滤器可能更容易。我也在Unix过滤器模型之后编写了这个(从STDIN
读取,写入STDOUT
)因为这使得程序更加灵活(而且,有趣的是,更容易编写!)
假设您在Linux(或类似版本)上运行该程序并且您的代码位于名为my_filter
的可执行文件中(我建议使用更具描述性的名称!),那么您可以这样称呼它:< / p>
$ my_filter < 5PCZ.pdb > 5PCZ.pdb.new
代码如下所示:
#!/usr/bin/perl
use strict;
use warnings;
while (<>) { # read from STDIN a line at a time
# Split data on whitespace, but only into four columns
my @cols = split /\s+/, $_, 4;
next unless $cols[0] eq 'FORMUL';
# Now extract the letter stuff into a hash for easy access.
# We extract letters from the final column in the record.
my %letters = $cols[-1] =~ m/([A-Z])(\d+)/g;
# Give the values we're interested in, a default of 0
$letters{$_} //= 0 for (qw[C O N]);
next if $letters{C} > 2
and $letters{C} + $letters{O} + $letters{N} >= 6;
# I think we can then print the line;
print;
}
这似乎为您的示例数据提供了正确的输出。我希望这些评论能够明确如何调整条件。