2

我正在尝试编写一个 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";
4

1 回答 1

0

我会试着理解你想做什么。

我正在尝试编写一个 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 的元素。当我们点击开始索引时,“连接”开始,并且此连接处于活动状态,直到到达终点。

我们将所有值存储到当前条目。

当我们点击“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);
于 2013-02-05T08:28:48.843 回答