2016-07-05 3 views
0

Информация о том, что делает скрипт, не имеет значения, но я поставил комментарии в то, что кажется важными для меня, меня интересует только то, почему я получаю пустые строки в моем выходеПочему пустые строки печатаются в моем скрипте для печати perl?

Когда я запустить команду

./script.pl temp temp.txt tempF `wc -l temp | awk '{print $1}'` 

файл содержит временный

1 27800000 120700000 4 
1 27800000 124300000 4 
1 154800000 247249719 3 
0000 71800000 9 
0000 87200000 2 
3 54400000 74200000 15 
4 76500000 155100000 20 
4 76500000 182600000 3 
4 76500000 88200000 77 
4 88200000 124000000 2 
5 58900000 180857866 8 
5 58900000 76400000 2 
5 58900000 97300000 4 
5 76400000 143100000 14 
5 97300000 147200000 6 
6 7000000 29900000 2 
6 63500000 70000000 73 
6 63500000 92100000 4 
6 70000000 113900000 70 
6 70000000 139100000 57 
6 92100000 113900000 3 

A ой я получаю выход формы

hs1 27800000 124300000 4 


hs0000 87200000 2 
hs3 54400000 74200000 15 

hs4 76500000 182600000 3 
hs4 76500000 88200000 77 
hs4 88200000 124000000 2 

hs5 58900000 76400000 2 
hs5 58900000 97300000 4 
hs5 76400000 143100000 14 
hs5 97300000 147200000 6 


hs6 63500000 92100000 4 

hs6 70000000 139100000 57 
hs6 92100000 113900000 3 

на стандартный вывод (около 8 линий также печатаются в файл temp.txt но форматирование тех из них является правильным)

Это сценарий ниже

#!/usr/bin/perl 

# ARGV[0] is the name of the file which data will be read from(may have overlaps) 
# ARGV[1] is the name of the file which will be produced that will have no overlaps 
# ARGV[2] is the name of the folder which will hold all the data 
# ARGV[3] is the number of lines that ARGV[0] will contain 

use warnings; 

my $file = "./$ARGV[0]"; 
my @lines = do { 
    open my $fh, '<', $file or die "Can't open $file -- $!"; 
    <$fh>; 
}; 

my $file2 = "./$ARGV[2]/$ARGV[1]"; 
open(my $files, ">", "$file2") or die "Can't open > $file2: $!"; 

my $i = 0; 
while ($i < $ARGV[3] - 1) { 

    my @ref_fields = split('\s+', $lines[$i]); 

    print $files 
     "$ref_fields[0]", "\t", 
     $ref_fields[1], "\t", 
     $ref_fields[2], "\t", 
     $ref_fields[3], "\n"; 

    for my $j ($i + 1 .. $ARGV[3] - 1) { 

     $i = $j; 

     # @curr_fields is initialized here 

     my @curr_fields = split /\s+/, $lines[$j]; 

     if ($ref_fields[0] eq $curr_fields[0] && $ref_fields[2] > $curr_fields[1]) { 

      if (defined($curr_fields[0]) && $curr_fields[0] !~ /\s+/) { 

       chomp $curr_fields[3]; 

       # the line below is the one that is printing to standard output 
       print 
        $curr_fields[0], "\t", 
        $curr_fields[1], "\t", 
        $curr_fields[2], "\t", 
        $curr_fields[3], "\n"; 
      } 
     } 
     else { 
      last; 
     } 
    } 

    print "\n"; 
} 

.

.

Edit:

Я заметил ошибку при запуске сценария из послать ответ Когда я запускаю команду

./script.pl temp1 temp10.txt folder 

Где TEMP1 содержит

12 58100000 96200000 0.04348 
3 74200000 87200000 0.04348 
5 130600000 168500000 0.04348 
6 61000000 114600000 0.04348 
6 75900000 114600000 0.04348 
6 88000000 114600000 0.04348 
6 88000000 139000000 0.04348 
6 93100000 161000000 0.04348 
6 105500000 139000000 0.04348 
6 130300000 139000000 0.04348 
7 59900000 77500000 0.04348 
7 98000000 132600000 0.04348 
X 67800000 76000000 0.08696 
Y 28800000 59373566 0.04348 

Я получаю

6 75900000 114600000 0.04348 
6 88000000 114600000 0.04348 
6 88000000 139000000 0.04348 
6 93100000 161000000 0.04348 
6 105500000 139000000 0.04348 

И temp10.txt содержит

12 58100000 96200000 0.04348 
3 74200000 87200000 0.04348 
5 130600000 168500000 0.04348 
6 61000000 114600000 0.04348 
6 130300000 139000000 0.04348 
7 59900000 77500000 0.04348 
7 98000000 132600000 0.04348 
X 67800000 76000000 0.08696 

Линия

Y 28800000 59373566 0.04348 

ни на выходе или temp10.txt. Это, кажется, dissappeared, но должны были напечатаны в одном из них

ответ

2

Кажется очевидным, что пустые строки печати, потому что у вас есть линия

print "\n"; 

в коде

Я не могу помочь гораздо больше, потому что вы говорите «подробности того, что скрипт делает это не важно», и поэтому воздержитесь от нас, что это означало , чтобы делать

Однако то, что вы написали, печатает строки из входного файла, если первый столбец соответствует первому столбцу в предыдущей строке, а второе поле меньше третьего поля в предыдущей строке.Каждый раз, когда вы получаете строку, которая не удовлетворяет критериям, таким образом, вы печатаете пустую строку



Вы можете предпочесть этот рефакторинг кода, который ведет себя одинаково, но я думаю, что намного больше удобочитаемый. Он также имеет преимущество разбиения каждой из строк из входного файла только один раз, и нет необходимости в четвертом параметре, поскольку количество строк - это просто размер массива @lines. Пустые строки не будут удалены из файла, как они читают, так что больше нет необходимости для проверки на корректность первого поля

#!/usr/bin/perl 

# ARGV[0] is the name of the file which data will be read from (may have overlaps) 
# ARGV[1] is the name of the file which will be produced that will have no overlaps 
# ARGV[2] is the name of the folder which will hold all the circos data file (mitelmanAll, mitelmanProstate, etc.) 

use strict; 
use warnings 'all'; 

use File::Path 'make_path'; 
use File::Spec::Functions 'catfile'; 

my ($file, $newfile, $dir) = @ARGV; 
$newfile = catfile($dir, $newfile); 

my @lines = do { 
    open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!}; 
    map { [ split ] } grep /\S/, <$fh>; 
}; 

make_path($dir); 
open my $out_fh, '>', $newfile or die qq{Unable to open "$newfile" for output: $!}; 

for (my $i = 0; $i < $#lines;) { 

    my $ref_fields = $lines[$i]; 

    print $out_fh join("\t", @$ref_fields[0..3]), "\n"; 

    for my $j ($i + 1 .. $#lines) { 

     $i = $j; 

     my $curr_fields = $lines[$j]; 

     last unless $curr_fields->[0] == $ref_fields->[0]; 
     last unless $curr_fields->[1] < $ref_fields->[2]; 

     print join("\t", @$curr_fields[0..3]), "\n"; 
    } 
} 
+0

Ха-ха, да, что это было, я дурак – Jacob

+0

Как являюсь распечатывая пустую строку, когда я получаю строку, которая не соответствует этому условию, если условие не выполняется, должен быть выполнен только последний элемент. – Jacob

+0

@ C.Monster: Да, поэтому 'last' выходит из цикла' for', после чего появляется «print» \ n "' до конца 'while'. Взгляните на мое предложение переписать. Он делает то же самое, что и ваш собственный код, но я его читаю гораздо легче! – Borodin

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