2015-03-24 2 views
1

Я пытаюсь удалить несколько символов из большого текстового файла (около 1 ГБ). Файл содержит примерно так:удалить несколько символов в большом файле, используя perl

>chr1 
NNNNNNNNNNNNN 
NNNNNNATGGGGA 
NNNNNNNNNNNNN 
AGCGTAGGCGACG 

>chr2 
NNNNNNNNNNNNN 
ATGCGTAGCGCAT 
NNNNNNNNGCATG 
CGATGCTAGctag 
cgatcgagcgatg 

Я хочу, чтобы получить только характер «ATCG» и хочу объединить все строки, так оно должно выглядеть следующим образом:

ATGGGGAAGCGTAGGCGACGATGCGTAGCGCATGCATGCGATGCTAGCTAGCGATCGAGCGATG 

К сожалению, все нежелательному символы были заменены на пробелы так:

ATGGGGA 


AGCGTAGGCGACG 


ATGCGTAGCGCAT 

Я что-то упустил? Это мой код:

open FH, "<", 'filename' or die "Can't open\n"; #read the file 

while (my $load = sysread (FH, $temp, 1e+8)) { 
    warn "Read $load bytes\n"; 

    $temp =~ s/>chr+//gi; 
    $temp =~ s/\d+//g; 
    $temp =~ s/n+//gi; 

    chomp($temp); 
    $process .= uc($temp); 
    $temp = ''; 
} 

open (FH, ">", 'newfile') or die "Can't create\n"; #processed string in new file 

print FH $process; 
close FH; 

Заранее благодарен.

ответ

2

Вы снимаете персонажей, но вы не трогаете линейные каналы. Я предполагаю, что это то, что вы пытаетесь с:

s/n+//g; 

Это должен быть \n. chomp не будет делать трюк - это только удаляет перевод строки в конце строки.

s/chr+//g; 

также не будет делать то, что вы хотите - это в буквальном смысле ch тогда one or more instances of "r".

Учитывая, что в вашем файле есть переводы строк, есть ли какая-то конкретная причина, по которой вам нужно прочитать всю партию за один раз? Я бы предположить:

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

open (my $input, "<", "input_file_name") or die $!; 
open (my $output, ">", "output_file_name") or die $!; 
while (my $line = <$input>) { 
    next if $line =~ m/^>/; 
    $line =~ s/[^ATCG]//gi; 
    print {$output} $line; #NB - no linefeeds at all. 
} 

close ($input); 
close ($output); 

Дает:

ATGGGGAAGCGTAGGCGACGATGCGTAGCGCATGCATGCGATGCTAGCTAG 
+0

Спасибо за ответ. Я не уверен, что вы имеете в виду, прочитав «всю судьбу». Я читаю файл чашкой, так как файл очень большой. Я понимаю, что ваш код способен извлекать только «ATGC». Как насчет «atgc»? Я сожалею, что забыл включить и нижний регистр. – irwan

+1

Да, но вы делаете это через sysread из нескольких байтов, что не похоже на ваши потребности. Я делаю прописные буквы, потому что ваш образец был в верхнем регистре. Если вы хотите снизить также, используйте 's/^ [ATCG] // ig' (и снова используйте' uc') – Sobrique

+0

's/^ [ATCG] // ig' может извлечь все нижние регистры, но это также извлеките 'c' в '> chr1'. Как удалить '> chr1'? – irwan

0

Самый простой способ сделать это

tr -cd ATCG <input> output 

См tr. Или в Perl

perl -pe'y/ATCG//cd' input > output 

См perlrun документации для -pe смысла и perlop для y// и cd модификаторов.

Смежные вопросы