私が作業しているファイルの小さなスニペットがあります:
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
}
各行について:
- 最初の列が「データベース」に存在するかどうかを確認します
- そうでない場合は、「データベース」に追加し、行全体を印刷します。
答え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