詳しく説明する前に、この質問の一部をすでに質問していることを指摘したいと思います。 ->ここで見つけることができます。。いくつかの良い回答を受けましたが、もっと多くのことをする必要があるので、今回は質問を繰り返して詳細を追加します。
そのため、次のような独自のコンテンツを含むファイルがあります(と呼びます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番目の場所で終わるため、この数/順位は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
このスクリプトは、一時ファイルを生成せずにランクを計算します(ほぼ1つ作成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スクリプトは、一度に2つのファイルを繰り返しながら、方法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
スクリプトは両方のファイルのヘッダー行を完全に無視するので、現在のアルゴリズムがその行番号を計算する場合、その行番号は1つ減らすことができます。
また、一意のファイルの値は、常に重複ファイルの同じ値のすぐ隣に並べられると仮定します。あなたが望んでいない場合は、ループ<
の比較for my $i (0..@phylop)
を<=
。
方法1と方法2のそれぞれに値が必要な場合は、簡単に抽出できますawk
。あるいは、perl
スクリプトを簡単に変更して、各メソッドに1つずつ2つの出力ファイルを開き、その値を各ファイルに印刷することもできます。
入力行の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
一度に1行ずつ消費するように指示されます。これは、ループ内に$line
ファイルの1行があることを意味しますsample
。変数はファイルcat
を生成するためにエコーされパイプされますmyDuplicated*
。ただし、ファイルは「即時」作成され、ディスクに書き込まれません。tail
ファイルがソートされる前にヘッダー行が削除されます。awk
次に、サンプルがどの行にあるかを調べるために使用されます。
編集する:私の考えには利点があると思いますがsplit
、この答えを使うと中間ファイルは必要ありません。