
次のファイルがあります。
1 7.8e-12
1 7.8e-12
1 1.0e-11
2 9.3e-13
2 3.5e-12
2 3.5e-10
2 3.1e-9
3 3.0e-11
3 3.0e-11
3 1.7e-08
最初の列の各値について、2番目の列の最小値を持つ「すべての行」を選択し、最初の列に基づいてグループ化したいと思います。したがって、希望の出力は次のようになります。
1 7.8e-12
1 7.8e-12
2 9.3e-13
3 3.0e-11
3 3.0e-11
これを行う方法を知っていますか?
答え1
1つの方法は、昇順にソートしてから、各col1の最初のcol2値を記録し、現在のcol2値が等しいかどうかを印刷することです。
sort -k1,1n -k2,2g file | awk '!a[$1] {a[$1] = $2} $2 == a[$1]'
1 7.8e-12
1 7.8e-12
2 9.3e-13
3 3.0e-11
3 3.0e-11
答え2
科学的表記法で数字を処理する必要があります。
awk '
NR == FNR {
if (!($1 in min) || $2 < min[$1])
min[$1] = $2
next
}
$2 == min[$1]
' file file
ファイルを2回処理します。一度は各キーの最小値を見つけ、その最小値を持つ行を出力します。
答え3
テキスト処理ベースの回答を完了するためにPostgreSQLを使用してこれを行う方法は次のとおりです。
まず、簡単にインポートできるようにファイルを前処理してCSVに変換します。
awk -v OFS=, '$1=$1' file.txt > file.csv
次に、PostgreSQLで次のように一時テーブルを作成します。
create temp table x (id int, bignum float);
CSVをコピーします。
\copy x from file.csv with (format csv)
目的の結果を得るには、一時テーブルに問い合わせてください。
select id, bignum
from (
select
*,
rank() over (partition by id order by bignum)
as rank
from x
) as sqlrequiresthisalias
where rank = 1;
結果:
id | bignum
----+---------
1 | 7.8e-12
1 | 7.8e-12
2 | 9.3e-13
3 | 3e-11
3 | 3e-11
(5 rows)
答え4
牛に似た一種の栄養awk
解決策:
awk 'BEGIN{ PROCINFO["sorted_in"] = "@val_num_asc" }
{ a[$1][++c] = $2 }
END{
for (i in a) {
prev = 0;
for (j in a[i]) {
v = a[i][j]; if (prev && v != prev) continue;
print i, v; prev = v
}
}
}' file
出力:
1 7.8e-12
1 7.8e-12
2 9.3e-13
3 3.0e-11
3 3.0e-11