IDペアと、より高い値とより低い値に基づいてファイルを解析します。

IDペアと、より高い値とより低い値に基づいてファイルを解析します。

File1には8つの列があります。列3と4は、rs | 860 rs | 756のようなペアを形成し、このペアに関連する値は列8にあります。

bb  yy  rs|860  rs|756  xx  aa  0.7 2234
bb  yy  rs|310  rs|260  xx  aa  0.3 9838
bb  yy  rs|110  rs|77   xx  aa  0.5 2291
bb  yy  rs|756  rs|860  xx  aa  0.4 2269
bb  yy  rs|110  rs|77   xx  aa  0.9 1112
bb  yy  rs|756  rs|860  xx  aa  0.8 3269
bb  yy  rs|233  rs|79   xx  aa  0.4 1397
bb  yy  rs|79   rs|233  xx  aa  0.7 1397

列3と4、または4と3のペアは同じように処理する必要があります(例:rs | 860 rs | 756 == rs | 756 rs | 860)。次に、1行のペアが4行と6行にも現れることがあります(またはその逆)。簡単に言えば、AB = BA = BAです。まず、col3とcol4を行ごとにソートして、AB = AB = ABのようなデータを作成したいと思います。次に、発生するすべてのペアのうち1つだけが列8の最大値を維持する必要があります。たとえば、rs | 860 rs | 756は行6(つまり3269)に最大値があるため、行1と4を削除する必要があります。同様に、rs | 110の場合は、rs | 77 row5を削除する必要があります。次に、列8に同じ値を持つペアがある場合は、列7に高い値を持つペアを維持する必要があります。たとえば、rs | 233 rs | 79 row7の場合、列7の下位値(0.4)を削除する必要があります。すべてのペアについて、列8と列7の間に高い/低い差がない場合は、どちらかを削除できます。

希望の出力 File2

bb  yy  rs|260  rs|310  xx  aa  0.3 9838
bb  yy  rs|77   rs|110  xx  aa  0.5 2291
bb  yy  rs|756  rs|860  xx  aa  0.8 3269
bb  yy  rs|79   rs|233  xx  aa  0.7 1397

答え1

これはエレガントではないawkソリューションです。

{
    split($3, a, "|")
    split($4, b, "|")
    if (a[2] > b[2]){
        $3=b[1]"|"b[2]
        $4=a[1]"|"a[2]
    }
    split(arr[$3" "$4], c, " ")
    if ($8 > c[8]){
        arr[$3" "$4] = $0
    }
}
END{
    for (item in arr){
        print(arr[item])
    }
}

次に実行

awk -f script.awk input

間隔は維持されず、順序はランダムです。

答え2

確立されたpfnueselの答え

{
    split($3, a, "|")
    split($4, b, "|")
    if (a[2] > b[2]){
        $3=b[1]"|"b[2]
        $4=a[1]"|"a[2]
    }
    key=$3" "$4
    split(arr[key], c, " ")
    if ($8 > c[8]  ||  ($8 == c[8] && $7 > c[7])){
        arr[key] = $0
    }
}
END{
    for (item in arr){
        print(arr[item])
    }
}

質問に示すように(明示的に言及されていない)、3番目と4番目の列の値が次の形式であるとします。

some_string|数字

スペースは説明目的でのみ使用され、ひも文字が含まれていません|。このタグは以下に基づいています。数字s;これひもプレフィックスは比較されません。

のようにpfnueselの答え、使用法は

awk -f script.awk file1

入力ファイルの正確な間隔は失われますが、読み取ることができる列間隔は、パイピングによって(再)生成することができます column -t

awk -f script.awk file1 | column -t > file2

関連情報