ファイルを複数回コピーする、重複ファイルを書き込む、ファイルを並べ替える、並べ替え後の特定の行の位置を計算する

ファイルを複数回コピーする、重複ファイルを書き込む、ファイルを並べ替える、並べ替え後の特定の行の位置を計算する

詳しく説明する前に、この質問の一部をすでに質問していることを指摘したいと思います。 ->ここで見つけることができます。。いくつかの良い回答を受けましたが、もっと多くのことをする必要があるので、今回は質問を繰り返して詳細を追加します。

そのため、次のような独自のコンテンツを含むファイルがあります(と呼びます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に行(ヘッダーを除く)を追加したいのですが、 myUniqueFilefromに追加されたすべての新しい行で繰り返される方法で追加したいと思いますmyDuplicationFile。したがって、標準コンテンツを維持して新しい行を1つ追加してください。次のようにする必要があります。myDublicationFilemyUniqueFilemyDublicationFilemyUniqueFile

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

splitGNUバージョンがあり、または同じシェルをcoreutils使用できると仮定すると(ここで使用されているプロセス置換機能について)、ヘッダー行とソートを処理するために以前に許可された回答を変更できます。bashkshzsh

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"'

その後、単純な行を使用して出力ファイル内の項目の場所を見つけることができますawkmyUniqueFile

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、この答えを使うと中間ファイルは必要ありません。

関連情報