1

我有一个 Perl 问题。我有一个文件,该文件的每一行都包含不同数量的 As Ts Gs 和 Cs 该文件如下所示

ATCGCTGASTGATGCTG
GCCTAGCCCTTAGC
GTTCCATGCCCATAGCCAAATAAA 

我想为每一行添加行号然后每 6 个字符插入一个 \n,然后在创建的每个新行上每 3 个字符放置一个空白空间

输出示例应为

Line NO 1                   
ATC GCT
GAS TGA
TGC TG

Line NO 2
GCC TAG
CCC TTA
GC 

我想出了下面的代码:

my $count = 0;
     my $line;
     my $row;
     my $split;
     open(F, "Data.txt") or die "Can't read file: $!";
     open (FH, " > UpDatedData.txt") or die "Can't write new file: $!";
     while (my $line = <F>) {
      $count ++ ;
      $row = join ("\n",  ( $line =~ /.{1,6}/gs));
      $split = join ("\t",  ( $row =~ /.{3}/gs ));
      print FH "Line NO\t$count\n$split\n";
    }
    close F;
    close FH;

然而

它给出了以下输出

Line NO 1                   
ATC GCT
GA  STG A
T   GCT G

Line NO 2
GCC TAG
CC  CTT A
G   C 

这必须有一些东西, \n 在这行代码中被算作一个字符

$split = join ("\t",  ( $row =~ /.{3}/gs ));

有人知道如何解决这个问题吗?

任何帮助将不胜感激。

提前致谢

西奈德

4

3 回答 3

1

这应该可以解决您的问题:

use strict;
use warnings;

while (<DATA>) {
  s/(.{3})(.{0,3})?/$1 $2 /g;
  s/(.{7}) /$1\n/g;

  printf "Line NO %d\n%s\n", $., $_;
}

__DATA__
ATCGCTGASTGATGCTG
GCCTAGCCCTTAGC
GTTCCATGCCCATAGCCAAATAAA
于 2012-12-05T16:35:40.760 回答
0

这是一个单行:

perl -plwe 's/(.{3})(.{0,3})/$1 $2\n/g' data.txt

正则表达式查找 3 个字符(不匹配换行符),后跟 0-3 个字符并捕获这两个字符,然后在它们之间插入一个空格并在其后插入一个换行符。

要跟踪行号,您可以添加

s/^/Line NO $.\n/;

它将根据输入的行号进行枚举。如果您愿意,可以保留一个简单的计数器,例如++$i.

  • -l选项将为您处理换行符。

您也可以分两个阶段执行此操作,如下所示:

perl -plwe's/.{6}\K/\n/g; s/^.{3}\K/ /gm;'

在这里使用\K(keep) 转义序列来保留字符串的匹配部分,然后在 6 个字符后简单地插入一个换行符,然后在“行开头”之后插入一个空格 3 个字符,它带有/m修饰符也包括换行符。

所以,简而言之:

perl -plwe 's/.{6}\K/\n/g; s/^.{3}\K/ /gm; s/^/Line NO $.\n/;' data.txt
perl -plwe 's/(.{3})(.{0,3})/$1 $2\n/g;    s/^/Line NO $.\n/;' data.txt
于 2012-12-05T15:54:25.533 回答
0

另一种解决方案。请注意,它使用词法文件句柄open.

#!/usr/bin/perl
use warnings;
use strict;

open my $IN,  '<', 'Data.txt'        or die "Can't read file: $!";
open my $OUT, '>', 'UpDatedData.txt' or die "Can't write new file: $!";
my $count = 0;
while (my $line = <$IN>) {
    chomp $line;
    $line =~ s/(...)(...)/$1 $2\n/g;         # Create pairs of triples
    $line =~ s/(\S\S\S)(\S{1,2})$/$1 $2\n/;  # A triple plus something at the end.
    $line .= "\n" if $line !~ /\n$/;         # A triple or less at the end.
    $count++;
    print $OUT "Line NO\t$count\n$line\n";
}
close $OUT;
于 2012-12-05T16:16:03.673 回答