あるフィールドに基づいて一意の行をソートし、別のフィールドに基づいて出力する行を決定します。

あるフィールドに基づいて一意の行をソートし、別のフィールドに基づいて出力する行を決定します。

これは問題に対する優雅な解決策を見つけることであり、私は効果的な解決策を持っていると思います。私のUbuntuコンピュータには、次のような入力ファイル形式(タブ区切り)があります。

AC003665.1  17  47813266    AGCAGGCGCA  83
RIOK3   18  23453502    GCAAGGCCCC  52
UBE2Z   17  48910880    CTAAGGATCC  48
CSNK1D  17  82251379    AATTTAGCCA  68
CSNK1D  17  82251379    AATTTCTTGT  38
SMURF1  7   99143726    GACAGATTGG  74
SMURF1  7   99143726    GACAGATTGG  61
RIOK3   18  23453502    GCAAGACTTT  69

フィールド3が発生するたびに、1つの行、つまりフィールド5で最も高い値を持つ行を取得したいと思います。したがって、出力は次のようになります。

AC003665.1  17  47813266    AGCAGGCGCA  83
CSNK1D  17  82251379    AATTTAGCCA  68
UBE2Z   17  48910880    CTAAGGATCC  48
SMURF1  7   99143726    GACAGATTGG  74
RIOK3   18  23453502    GCAAGACTTT  69

順序は私の目的とは関係ありません。まず、フィールド5でソートしてから、フィールド3でソートするソリューションを見つけました。これがうまくいくと思います。

sort -k 5,5nr input | sort -u -k 3,3n > output

これはすべてのテストファイルで機能し、どのような場合でも機能する必要があると思います。これは、フィールド3のすべての値に対してソートが最初にフィールド5の値が最も高い行をチェックして保持するためです。

しかし、この問題に対するもう少しエレガントな(多分より確実な)解決策があるべきだと思います。助けてくれてありがとう。

ベストアンサー1

出力するデータがメモリに入るほど小さい場合

awk '
    biggest[$3] < $5 { biggest[$3]=$5 ; saved[$3]=$0 }
    END { for (i in saved) { print saved[i] }}' 

通常、この方法がより高速で保存する必要があるかどうかを判断するときは、各行を一度見てください。メモリ要件は出力されるデータによって異なりますので、非常に反復的な入力は非常に大きくなる可能性があります。

これは、行ごとに複数の比較が必要なソートソリューションとは対照的です。ソートベースのソリューションは、速度が遅くても大きすぎてメモリに収まらない出力を処理します。

おすすめ記事