/ / Perl - dodawanie nowych znaków linii i tabulacji po ustalonej liczbie znaków w pliku? - perl, manipulacja danymi

Perl - dodawanie nowych znaków linii i tabulacji po ustalonej liczbie znaków w pliku? - perl, manipulacja danymi

Mam pytanie dotyczące Perla. Mam plik, każda linia tego pliku zawiera inną liczbę As Ts Gs i Cs Plik wygląda jak poniżej

ATCGCTGASTGATGCTG
GCCTAGCCCTTAGC
GTTCCATGCCCATAGCCAAATAAA

Chciałbym dodać numer linii dla każdej linii Następnie wstaw n co 6 znaków, a następnie na każdym z nowych utworzonych wierszy umieść Puste miejsce co 3 znaki

Przykład wyjścia powinno być

Line NO 1
ATC GCT
GAS TGA
TGC TG

Line NO 2
GCC TAG
CCC TTA
GC

Wymyśliłem poniższy kod:

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 NOt$countn$splitn";
}
close F;
close FH;

jednak

Daje to następujące rozwiązanie

Line NO 1
ATC GCT
GA  STG A
T   GCT G

Line NO 2
GCC TAG
CC  CTT A
G   C

To musi mieć coś, w którym n jest liczone jako znak w tym wierszu kodu

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

Ktoś ma pomysł, jak obejść ten problem?

Każda pomoc będzie bardzo ceniona.

Z góry dziękuję

Sinead

Odpowiedzi:

0 dla odpowiedzi № 1

Jest to jeden liniowiec:

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

Wyrażenie wyszukuje 3 znaki (nie pasuje do nowej linii), a następnie 0-3 znaków i przechwytuje obie te wartości, a następnie wstawia spację między nimi i znak nowej linii.

Aby śledzić numery linii, możesz dodać

s/^/Line NO $.n/;

Które będą wyliczać na podstawie numeru linii wejściowej. Jeśli wolisz, możesz zachować prosty licznik, na przykład ++$i.

  • -l opcja obsłuży nowe linie dla ciebie.

Możesz również zrobić to w dwóch etapach, na przykład:

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

Używając K (trzymaj) sekwencję escape tutaj, aby zachować dopasowaną część napisu, a następnie po prostu wstawianie znaku nowej linii po 6 znakach, a następnie spacji 3 znaki po "początkach linii", co w przypadku /m modyfikator obejmuje również nowe linie.

Krótko mówiąc:

perl -plwe "s/.{6}K/n/g; s/^.{3}K/ /gm; s/^/Line NO $.n/;" data.txt
perl -plwe "s/(.{3})(.{0,3})/$1 $2n/g;    s/^/Line NO $.n/;" data.txt

1 dla odpowiedzi nr 2

To powinno rozwiązać Twój problem:

use strict;
use warnings;

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

printf "Line NO %dn%sn", $., $_;
}

__DATA__
ATCGCTGASTGATGCTG
GCCTAGCCCTTAGC
GTTCCATGCCCATAGCCAAATAAA

0 dla odpowiedzi № 3

Inne rozwiązanie. Zauważ, że używa leksykalne uchwyty plików i trzy formy argumentacji 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 $2n/g;         # Create pairs of triples
$line =~ s/(SSS)(S{1,2})$/$1 $2n/;  # A triple plus something at the end.
$line .= "n" if $line !~ /n$/;         # A triple or less at the end.
$count++;
print $OUT "Line NOt$countn$linen";
}
close $OUT;