2 列のファイルで一意の値が最初に出現する行を印刷するにはどうすればよいでしょうか?

2 列のファイルで一意の値が最初に出現する行を印刷するにはどうすればよいでしょうか?

私が作業しているファイルの小さなスニペットがあります:

ENSDARG00000032737    ENSDARP00000120731
ENSDARG00000032737    ENSDARP00000049290
ENSDARG00000061051    ENSDARP00000081062
ENSDARG00000061051     
ENSDARG00000061051    ENSDARP00000129708

最初の列の各一意の値の最初のインスタンスと、2 番目の列の対応する値のみを印刷したいので、必要な出力は次のようになります。

ENSDARG00000032737    ENSDARP00000120731
ENSDARG00000061051    ENSDARP00000081062

awk や uniq などでこれを実現する簡単な方法はありますか?

ご協力いただければ幸いです。

答え1

POSIX AWK:

m1[$1] == 0 {
   m1[$1] = 1
   print
}

各行について:

  1. 最初の列が「データベース」に存在するかどうかを確認します
  2. そうでない場合は、「データベース」に追加し、行全体を印刷します。

答え2

$ sort -s -k1,1 -u file
ENSDARG00000032737    ENSDARP00000120731
ENSDARG00000061051    ENSDARP00000081062

これは、最初の列のみに基づいてファイルをソートします。その際、最初の列がすでに表示されている行は無視されます。

のほとんどの実装には、sort非標準-sオプション (上記のコマンドで使用) があり、これによって「安定した」ソート アルゴリズムが使用されることが保証されます。安定したソート アルゴリズムでは、同一のキー (この場合は最初の列) を持つエントリの順序は変更されません。


ただし、EnsemblとHavanaの両者が100%同意している、より長いトランスクリプトは、ENSDARG00000032737遺伝子は ENSDART00000049291 であり、ENSDARP00000049290 をコード化しており、ENSDARP00000120731 をコード化しているわけではありません。しかし、それは私の仕事ではありません。

答え3

この慣用的な解決策は、あらゆる UNIX ボックス上のあらゆるシェルのあらゆる awk を使用して確実に機能します。

$ awk '!seen[$1]++' file
ENSDARG00000032737    ENSDARP00000120731
ENSDARG00000061051    ENSDARP00000081062

答え4

最良の解決策はすでに提供されており、私の試みを投稿しただけです

for i in `awk '{if(!seen[$1]++)print $1}' filename`; do sed -n '/'$i'/{p;q}' filename; done

出力

ENSDARG00000032737    ENSDARP00000120731
ENSDARG00000061051    ENSDARP00000081062

関連情報