我正在尝试写一个Perl脚本,其中一个字符串在每次出现'E‘时都会被分段,当用户通过命令行输入'C’的位置时(例如3-8或3-8,13-18或任何逗号分隔的位置,如果字符串很长,根据字符串的格式,这些位置是'C‘),包含'C’的片段(比如在3和8个位置)应该结合在一起并显示在输出中。假设字符串是"ABCDEABCDEABCDEABCDEABCDE“,用户输入3-8,那么程序输出应该是-
ABCDEABCDE
ABCDE
ABCDE
ABCDE
我写了一个脚本,用户通过命令行输入'C‘的位置,字符串在'E’的每个位置都被剪切,但之后我就不能正确地编写它了。请帮帮我!
到目前为止,我写的代码(编辑过的)是:
use strict;
use warnings;
my $s = 'ABCDEABCDEABCDEABCDEABCDE';
my $i=0;
my @where;
my @array;
my @bond;
my @pos;
my @s_array;
my @s_array2;
for ($i=0; $i<=4; $i++) {
$where[$i] = index($s,"C",$where[$i-1])+1;
push(@array,$where[$i]);
}
print "All Positions of C: @array\n\n";
print "Enter C positions:\n";
my @join_C = <STDIN>;
foreach (@join_C) {
@bond = split (',',$_);
}
foreach (@bond) {
@pos = split ('-', $_);
}
print "entered C positions:@pos\n";
print "Resulting disulfide linked peptides\n\n";
my @a = split(/E/, $s);
my $result = join ("E,", @a);
my @final = split(/,/, $result);
foreach my $final (@final) {
foreach my $pos(@pos) {
my @source = split //, $final[@final];
my $length = @source;
for ($i=0; $i<=$length; $i++) {
if (index($final[$i], "C") == $pos[$i]) {
push (@s_array, $final[$i]);
}
else {
push (@s_array2, $final[$i]);
}
}
}
}
my $lastly_joined = join (',', @s_array);
print "Joined Fragments= @s_array\n";
print "Remaining fragments= @s_array2\n";
发布于 2013-02-05 16:28:49
我会试着理解你想要做什么。
我正在尝试写一个Perl脚本,在这个脚本中,字符串在每次出现'E‘时都会出现片断
好的,首先创建输入。让我们使用一个数组来简化对元素的访问。
my @s = split ('', 'ABCDE' x 5);
我不确定这个字符串在你的情况下会是什么样子。你能提供一个真实世界的例子吗?
和当用户通过命令行输入'C‘的c_pos时(例如3-8或3-8,13-18或任何逗号分隔的'C’的c_pos,如果字符串很长,则根据这种格式的字符串)
我建议使用命令行参数。这使得以后在链中与其他工具一起使用脚本变得更容易。将参数传递给脚本:
script.pl 3-8,13-18
所以我们得到了一个配对列表:
my @pairs = split (',', join('', @ARGV));
现在,您应该检查传递的值是否指向‘C’。有效的组合存储在散列中,其中键是起始索引,值是结束索引。
my %c_pos;
foreach my $pair (@pairs) {
my ($from, $to) = split('-', $pair);
if (($string[$from-1] eq 'C') && ($string[$to-1] eq 'C')) {
$c_pos{$from-1} = $to-1;
} else {
warn "position ${from}-${to} not valid => ignored!\n";
}
}
包含'C‘的片段(比如在3和8个位置)应该连接在一起,并显示在输出中。
现在我们可以迭代@s的元素。当我们命中一个start索引时,一个‘connection’开始,这个连接是活动的,直到到达end为止。
我们将所有值存储到当前条目中。
当我们按下'E‘并且我们不在’连接‘中时,当前条目被推送到我们的结果,我们从下一个空条目开始。
for (my $i=0; $i<@string; $i++) {
if ($c_pos{$i}) {
$inside_connection = 1;
$end = $c_pos{$i};
} elsif ($i == $end) {
$inside_connection = 0;
$end = 0;
}
$entry.=$string[$i];
if ($inside_connection) {
# do not split on 'E'
} elsif ($string[$i] eq 'E') {
# split on 'E'
push @result, $entry;
$entry = '';
}
}
因为我不知道更好,所以我假设像3-8,8-13这样的链式连接会导致它的工作方式,就像你说的3-13。希望能符合你的要求。下面是完整的脚本:
use strict;
use warnings;
my @string = split ('', 'ABCDE' x 5);
my @pairs = split (',', join('', @ARGV));
my %c_pos;
foreach my $pair (@pairs) {
my ($from, $to) = split('-', $pair);
if (($string[$from-1] eq 'C') && ($string[$to-1] eq 'C')) {
$c_pos{$from-1} = $to-1;
} else {
warn "position ${from}-${to} not valid => ignored!\n";
}
}
my @result;
my $entry = '';
my $inside_connection = 0;
my $end=0;
for (my $i=0; $i<@string; $i++) {
if ($c_pos{$i}) {
$inside_connection = 1;
$end = $c_pos{$i};
} elsif ($i == $end) {
$inside_connection = 0;
$end = 0;
}
$entry.=$string[$i];
if ($inside_connection) {
# do not split on 'E'
} elsif ($string[$i] eq 'E') {
# split on 'E'
push @result, $entry;
$entry = '';
}
}
print join ("\n", @result);
https://stackoverflow.com/questions/12775191
复制相似问题