자세히 설명하기 전에, 이 질문의 일부를 이미 질문했다는 점을 지적하고 싶습니다. ->여기에서 찾을 수 있습니다.. 몇 가지 좋은 답변을 받았지만 더 많은 작업을 수행해야 하므로 이번에는 질문을 반복하고 세부 정보를 추가하겠습니다.
그래서 다음과 같은 고유한 콘텐츠가 포함된 파일이 있습니다(라고 부르겠습니다 myUniqueFile
).
chromosoom start end phylop GPS
chr1 28745756 28745756 7.905 5
chr1 31227215 31227215 10.263 5
chr1 47562402 47562402 2.322 4
chr1 64859630 64859630 1.714 3
chr1 70805699 70805699 1.913 2
chr1 89760653 89760653 -0.1 0
chr1 95630169 95630169 -1.651 -1
보시다시피, 이들은 점수가 다른 서로 다른 위치입니다.
다음과 같은 또 다른 파일이 있습니다 myDuplicationFile
.
chromosoom start end phylop GPS
chr3 15540407 15540407 -1.391 -1
chr3 30648039 30648039 2.214 3
chr3 31663820 31663820 0.713 3
chr3 33093371 33093371 3.753 4
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 39597927 39597927 8.721 5
따라서 먼저 from 에 행(헤더 제외)을 추가하고 싶지만 myUniqueFile
from 에 추가된 모든 새 행에서 반복되는 방식으로 추가하고 싶습니다 myDuplicationFile
. 따라서 표준 콘텐츠를 유지하고 새 줄 1개를 추가하세요. 다음과 같아야 합니다.myDublicationFile
myUniqueFile
myDublicationFile
myUniqueFile
myDublicatedFile1.txt:
chromosoom start end phylop GPS
chr3 15540407 15540407 -1.391 -1
chr3 30648039 30648039 2.214 3
chr3 31663820 31663820 0.713 3
chr3 33093371 33093371 3.753 4
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 39597927 39597927 8.721 5
chr1 28745756 28745756 0.905 1 <- first line from `myUniquefile`
myDublicatedFile2.txt:
chromosoom start end phylop GPS
chr3 15540407 15540407 -1.391 -1
chr3 30648039 30648039 2.214 3
chr3 31663820 31663820 0.713 3
chr3 33093371 33093371 3.753 4
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 39597927 39597927 8.721 5
chr1 31227215 31227215 10.263 5 <- second line from `myUniquefile`
따라서 새 줄이 추가될 때마다 새 파일이 생성되는 식입니다 myDublicatedFile3,4,5
.
새로 추가된 콘텐츠가 있는 후 myDublicatedFiles
이 파일의 특정 열을 높은 순으로 정렬하고 싶습니다(예:필롭열) 이렇게 하면 for f in myDublicatedFile* ; do sort -g -r -k 3 $f >> $f.method1.txt
다음과 같습니다.
myDuplicatedFile1.method1.txt:
chr3 39597927 39597927 8.721 5
chr1 28745756 28745756 7.905 5 <- count 2
chr3 33093371 33093371 3.753 4
chr3 30648039 30648039 2.214 3
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 31663820 31663820 0.713 3
chr3 15540407 15540407 -1.391 -1
chromosoom start end phylop GPS
따라서 이러한 파일을 정렬한 후 정렬 후에 추가된 줄의 위치를 알고 싶습니다. "grep"으로 뭔가를 하고 "count"를 사용하는 것이 나에게는 논리적인 것 같습니다.
따라서 myDublicatedFile1.method1.txt
추가된 줄이 myUniquefile
파일의 두 번째 위치에서 끝나기 때문에 이 개수/순위는 2입니다.
개수/순위를 계산한 후phlop
(방법 1)열을 정렬하고 싶습니다.GPS
(방법 2)열을 추가한 다음 추가된 행의 순위를 다시 계산합니다. myDuplicatedFile1.method1.method2.txt는 다음과 같아야 합니다.
chr3 39597927 39597927 8.721 5
chr1 28745756 28745756 7.905 5
chr3 33093371 33093371 3.753 4
chr3 30648039 30648039 2.214 3
chr3 31663820 31663820 0.713 3
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 15540407 15540407 -1.391 -1
chromosoom start end phylop GPS
개수/순위가 다른 파일에 기록되면 나중에 통계에 사용할 수 있으므로 쉽습니다. 따라서 가장 중요한 파일은 이 개수입니다. 결국에는 이 파일을 사용할 것이기 때문입니다. :)
그것은 다음과 같습니다:
countsForMethod1.txt:
29
3
5
6
50
etc.
countsForMethod2.txt:
7
3
21
45
etc..
답변1
split
GNU 버전이 있고 , 또는 같은 셸을 coreutils
사용할 수 있다고 가정하면(여기서 사용된 프로세스 교체 기능에 대해) 헤더 행과 정렬을 처리하기 위해 이전에 허용된 답변을 수정할 수 있습니다.bash
ksh
zsh
tail -n +2 myUniqueFile | SHELL=$(command -v bash) split -l1 --filter='{
head -n 1 myDuplicationFile &&
sort -g -r -k4,4 <(tail -n +2 myDuplicationFile) -
} > "$FILE"'
그런 다음 간단한 줄을 사용하여 출력 파일에서 항목 위치를 찾을 수 있습니다 awk
.myUniqueFile
awk 'FNR==NR && NR>1 {a[$0]++; next} ($0 in a) {print FILENAME, FNR}' myUniqueFile xa?
xaa 3
xab 2
xac 4
xad 5
xae 5
xaf 8
xag 9
다른 방법/정렬 순서를 위해 헹구고 반복합니다.
답변2
이 스크립트는 임시 파일을 생성하지 않고 순위를 계산합니다(거의 하나 생성 sorted_file
). 또한 myDuplicationFile
각 메서드를 한 번 정렬한 다음 나중에 사용합니다.
#!/bin/bash
rank_determination() {
# Sorts the "myDuplicationFile" one time
# The "sorted_file" will be used further.
###
tail -n +2 myDuplicationFile | sort -g -r -k "$1","$1" > sorted_file
# gawk iterates through "myUniqueFile" line by line (except the first line).
gawk -v field_number="$1" '
NR != 1 {
# Stores the needed value for the each line
###
search_value=$field_number
cnt=1
# then, it checks the specified column in the "sorted_file"
# line by line for the value, which is less than
# the "search_value" from the "myUniqueFile".
###
while((getline < "sorted_file") > 0) {
if($field_number < search_value)
break
cnt++
}
print cnt
# closing is needed for reading the file from the beginning
# each time. Else, "getline" will read line by line consistently.
###
close("sorted_file")
}' myUniqueFile
}
# I create a function, which takes
# the number argument, which means the column number:
# "4" for "phylop" column, "5" for the "GPS" column.
#
# The function creates output, which you can redirect
# to the needed file.
# Call this function multiple times with different arguments
# for the each needed column.
rank_determination 4 > method1.txt
rank_determination 5 > method2.txt
산출
tail -n +1 -- method*
==> method1.txt <==
2
1
3
4
4
7
8
==> method2.txt <==
2
2
3
5
6
7
8
답변3
@WeijunZhou가 그의 의견에서 말한 내용에 동의합니다. 이 작업을 수행하기 위해 이러한 임시 파일을 모두 만들 필요는 없습니다.
다음 Perl 스크립트는 한 번에 두 개의 파일을 반복하면서 방법 1(phylops) 및 방법 2(GPS) 정렬에 대한 개수를 계산합니다.
이는 중복 파일에 필롭 및 GPS 값의 정렬된 목록(배열)을 유지한 다음 (고유 파일의 각 행에 대해) 필롭 및 GPS 값이 있을 각각의 정렬된 배열에서 위치를 계산하는 방식으로 작동합니다. 정렬되었습니다.
#!/usr/bin/perl
use strict;
# get uniqfile and dupefile names from cmd line, with defaults
my $uniqfile = shift || 'myUniqueFile';
my $dupefile = shift || 'myDuplicationFile';
# Read in the dupefile and keep the phylops and GPS values.
# This could take a LOT of memory if dupefile is huge.
# Most modern systems should have no difficulty coping with even
# a multi-gigabyte dupefile.
my @phylop=();
my @GPS=();
open(DUPE,"<",$dupefile) || die "couldn't open '$dupefile': $!\n";
while(<DUPE>) {
chomp;
next if (m/^chromosoom/);
my($chr,$start,$end,$phylop,$GPS) = split;
push @phylop, $phylop + 0; # add 0 to make sure we only ever store a number
push @GPS, $GPS + 0;
};
close(DUPE);
# Sort the @phylop and @GPS arrays, numerically descending
@phylop = sort {$a <=> $b} @phylop;
@GPS = sort {$a <=> $b} @GPS;
print "Method1\tMethod2\n";
# Now find out where the phylop and GPS value from each line of uniqfile
# would have ended up if we had sorted it into dupefile
open(UNIQ,"<",$uniqfile) || die "couldn't open '$uniqfile': $!\n";
while (<UNIQ>) {
next if (m/^chromosoom/);
chomp;
my $phylop_sort_line=1;
my $GPS_sort_line=1;
my($chr,$start,$end,$phylop,$GPS) = split;
for my $i (0..@phylop-1) {
$phylop_sort_line++ if ($phylop < $phylop[$i]);
$GPS_sort_line++ if ($GPS < $GPS[$i]);
};
#printf "%i\t%i\t#%s\n", $phylop_sort_line, $GPS_sort_line, $_;
printf "%i\t%i\n", $phylop_sort_line, $GPS_sort_line;
};
close(UNIQ);
위에 제공한 샘플 데이터에 대해 실행하면 출력은 다음과 같습니다.
$ ./counts-for-methods.pl
Method1 Method2
2 1
1 1
3 2
4 3
4 5
7 7
8 7
스크립트는 두 파일의 헤더 줄을 완전히 무시하므로 현재 알고리즘이 해당 줄 번호를 계산하는 경우 해당 줄 번호는 하나가 줄어들 수 있습니다.
또한 고유 파일의 값은 항상 중복 파일의 동일한 값 바로 옆에 정렬된다고 가정합니다. 원하는 것이 아니라면 루프 <
의 비교 for my $i (0..@phylop)
를 <=
.
방법 1과 방법 2 각각에 대한 값이 필요한 경우 를 사용하여 쉽게 추출할 수 있습니다 awk
. 또는 perl
스크립트를 쉽게 수정하여 각 메소드마다 하나씩 두 개의 출력 파일을 열고 해당 값을 각 파일에 인쇄할 수 있습니다.
입력 행의 151개 필드를 처리하는 버전입니다. 그런 입력 파일이 없어서 코드에 주석 처리된 "5필드 버전"을 사용하여 테스트했습니다. 출력은 위 버전과 동일합니다.
#!/usr/bin/perl
use strict;
# get uniqfile and dupefile names from cmd line, with defaults
my $uniqfile = shift || 'myUniqueFile';
my $dupefile = shift || 'myDuplicationFile';
my @phylop=();
my @GPS=();
# Read in the dupefile and keep the phylops and GPS values.
# This could take a LOT of memory if dupefile is huge.
# Most modern systems should have no difficulty coping with even
# a multi-gigabyte dupefile.
open(DUPE,"<",$dupefile) || die "couldn't open '$dupefile': $!\n";
while(<DUPE>) {
chomp;
next if (m/^chromosoom/);
my @fields = split;
# 151 fields version:
push @phylop, $fields[42]+0;
push @GPS, $fields[150]+0;
# 5 fields version:
# push @phylop, $fields[3]+0;
# push @GPS, $fields[4]+0;
};
close(DUPE);
# Sort the @phylop and @GPS arrays, numerically descending
@phylop = sort {$b <=> $a} @phylop;
@GPS = sort {$b <=> $a} @GPS;
print "Method1\tMethod2\n";
# Now find out where the phylop and GPS from each line of uniqfile
# would have ended up if we had sorted it into the dupefile
open(UNIQ,"<",$uniqfile) || die "couldn't open '$uniqfile': $!\n";
while (<UNIQ>) {
next if (m/^chromosoom/);
chomp;
my $phylop_sort_line=1;
my $GPS_sort_line=1;
my @fields = split;
for my $i (0..@phylop-1) {
# 151 fields version:
$phylop_sort_line++ if ($fields[42] < $phylop[$i]);
$GPS_sort_line++ if ($fields[150] < $GPS[$i]);
# 5 fields version:
# $phylop_sort_line++ if ($fields[3] < $phylop[$i]);
# $GPS_sort_line++ if ($fields[4] < $GPS[$i]);
};
#printf "%i\t%i\t#%s\n", $phylop_sort_line, $GPS_sort_line, $_;
printf "%i\t%i\n", $phylop_sort_line, $GPS_sort_line;
};
close(UNIQ);
답변4
myUniqueFile
sample
입력 시간을 절약하기 위해 및 에 전화하겠습니다 myDuplicationFile
standard
.
#!/bin/bash
(
while read line; do
echo $line|cat standard -|tail -n +2|sort -g -r -k 4|awk '/^chr1/{print FNR}' >> countsForMethod1.txt
echo $line|cat standard -|tail -n +2|sort -g -r -k 5|awk '/^chr1/{print FNR}' >> countsForMethod2.txt
done
) <(tail -n +2 sample)
설명하다: 전체 while 루프는 한 쌍의 괄호로 묶여 bash
단일 명령으로 처리됩니다. 이 명령은 파일을 sample
입력으로 사용하고 이 명령을 사용하여 헤더 행을 제거합니다 tail
. 그런 다음 read
한 번에 한 줄씩 소비하도록 명령 됩니다 . 이는 루프 내부에 $line
파일의 한 줄이 있음을 의미합니다 sample
. 변수는 파일을 cat
생성하기 위해 에코되고 파이프됩니다 myDuplicated*
. 단, 파일은 "즉시" 생성되고 디스크에 기록되지 않습니다. tail
파일이 정렬되기 전에 헤더 행이 제거됩니다 . awk
그런 다음 샘플이 어느 행에 있는지 알아내는 데 사용됩니다.
편집하다: 제 생각엔 장점이 있다고 생각하는데 split
, 이 답변을 사용하면 중간 파일이 필요하지 않습니다.