#arrays #perl #sorting
#массивы #perl #сортировка
Вопрос:
Я пытаюсь отсортировать файл, который выглядит следующим образом
MarkerName Allele1 Allele2 Weight Zscore P-value Direction^Mrs217377 t c 6806 1.121 0.2625 ^Mrs4668077
a g 6806 -0.038 0.9696 -- ^Mrs16855496 a g 4106 -0.092 0.9268 ??-^Mrs217386 a g 6806
0.814 0.4158 ^Mrs2075070 a g 6806 -0.699 0.4844 -- ^Mrs10187002 a t 4106 0.099 0.9208 ?? ^Mrs12785983 t c 6806 -1.092 0.2747 --^Mrs1100405 t c 6806 -0.872 0.3831 --^Mrs12155014 t c
6806 0.081 0.9358 -^Mrs2287619 t c 6806 -2.221 0.02632 ---^M
После седьмого пробела вместо простого перевода строки стоит ^M
символ. Я не совсем уверен, как с этим бороться или я могу просто проигнорировать это.
Я пытаюсь отсортировать каждую строку по P-значению (шестому) столбцу.
Вот так:
MarkerName Allele1 Allele2 Weight Zscore P-value Direction
rs2287619 t c 6806 -2.221 0.02632 ---
rs217377 t c 6806 1.121 0.2625
rs12785983 t c 6806 -1.092 0.2747 --
rs1100405 t c 6806 -0.872 0.3831 --
rs217386 a g 6806 0.814 0.4158
rs2075070 a g 6806 -0.699 0.4844 --
rs10187002 a t 4106 0.099 0.9208 ??
rs16855496 a g 4106 -0.092 0.9268 ??-
rs4668077 a g 6806 -0.038 0.9696 --
Пока у меня есть этот Perl-код
use strict;
use warnings;
die "Please specify a suitable text filen" if (@ARGV != 1);
my ($infile) = @ARGV;
# create outputfile
my $outfile = "MetaAnalysis_Sorted.txt";
# create filehandles
open (my $in, " < $infile") or die "error reading $infile. $!";
open (my $out, " >> $outfile") or die "error creating $outfile. $!";
my @array;
while ( <$in> ) {
chomp; # removes newline
push @array, $_;
my @sorted = sort { (split 's', $a)[5] <=> (split 's', $b)[5] } @array;
print $out join( "n", @sorted )."nn";
}
close $in;
close $out;
Я пытался преобразовать исходный файл с помощью dos2unix
, но это не сработало.
Комментарии:
1. Символ возврата каретки (0x0d) отображается как
^M
в Vim, еслиfileformat=unix
. Просматриваете ли вы файл в Vim?2. Я просматриваю файл в Unix с помощью команды less, которая обычно отделяет возвраты каретки нормально, я не должен беспокоиться о сортировке, если я просматриваю в текстовом редакторе после?
3.
perl -pe 's/[rn] /n/' yourfile
4. Это помогло бы, но я никогда не рекомендую это кому-либо с командой example, потому что вмешиваться в чьи-либо исходные данные неприятно.
Ответ №1:
Основная проблема заключается в том, что вы используете 's'
литерал вместо регулярного выражения. Вероятно, вы имели в виду один или несколько пробелов, т.е. /s /
.
Другая проблема связана с nun-числовым, P-value
переданным <=>
оператору. Я предлагаю перед вызовом убрать заголовок из массива sort
.
Запись выходного файла должна выполняться вне while (<$in>)
цикла.
Кроме того, я предлагаю пропускать пустые строки:
while (<$in>) {
chomp; #removes new line
push @array, $_ if $_;
}
Вот исправленная версия:
use strict; use warnings;
die "Please specify a suitable text filen" if (@ARGV != 1);
my ($infile) = @ARGV;
#create outputfile
my $outfile = "MetaAnalysis_Sorted.txt";
#create filehandles
open (my $in, " < $infile") or die "error reading $infile. $!";
open (my $out, " >> $outfile") or die "error creating $outfile. $!";
my @array;
while (<$in>) {
chomp; #removes new line
push @array, $_ if $_;
}
my $head = shift @array;
print $out "$headn";
my @sorted = sort {
(split /s /, $a)[5] <=> (split /s /, $b)[5];
} @array;
print $out join( "n", @sorted )."nn";
close $in;
close $out;
Ответ №2:
Последовательность ^M
используется многими редакторами и текстовыми утилитами для обозначения Ctrl-M или возврата каретки. Похоже, что ваш файл был сохранен только с возвратом каретки (CR) в конце каждой строки. Это очень необычно. Linux использует только перевод строки (LF), в то время как Windows использует два символа CR LF. Только в гораздо более старых системах Macintosh использовался только CR
Последовательность символов регулярного выражения R
может быть очень полезна для файлов такого типа. Он будет соответствовать любому из LF, CR LF или просто CR. К сожалению, вы не можете установить разделитель строк ввода в соответствии с шаблоном регулярных выражений — это должна быть буквальная строка, поэтому вам придется прочитать весь файл в одну строку, а затем использовать split
Эта программа демонстрирует идею, но трудно сказать, где в ваших образцах данных могут появиться пустые строки, а также они искусственно перенесены в середину записей. Это должно работать нормально, если вы предоставляете неизмененный файл данных для ввода
sort_by_col6.pl
use strict;
use warnings 'all';
my @infile = do {
local $/;
split /R/, <>;
};
local $ = "n";
print shift @infile; # Print header line
print for sort { (split ' ', $a)[5] <=> (split ' ', $b) } @infile;
Вам нужно будет запустить его из командной строки следующим образом, чтобы перенаправить вывод
$ perl sort_by_col6.pl my_input.txt > MetaAnalysis_Sorted.txt