非常に大きなテーブルがあり、特定の行を抽出する必要があります。簡単な例として、これを説明します。私はリンゴ、バナナ、オレンジの重量を量ったとしましょう。リンゴ、バナナ、オレンジの最小重量を抽出する必要があります。
元のテーブル:
Apple 3
Banana 8
Orange 2
Apple 7
Banana 9
Orange 13
Apple 9
Banana 1
Orange 11
希望の出力:
Apple 3
Banana 1
Orange 2
答え1
そしてgnu
datamash
:
datamash -s -g 1 min 2 <infile
iPhone 3 バナナ1 オレンジ2
このジョブは、stフィールドに基づいてs
ソートおよびグループ化され、最初のフィールドの各IDのndフィールドの値を印刷します。g
フィールドが単一のタブ文字で区切られていると仮定します。複数のスペースで区切ったり、別のフィールド区切り記号(たとえば、単一のスペース)を定義したりする場合は、次のようにします。1
min
2
-W, --whitespace
-t, --field-separator=
datamash -t' ' -s -g 1 min 2 <infile
入力をソートする必要があるため、datamash
出力も最初のフィールドに基づいてソートされます。
答え2
そしてawk
:
$ awk '($2<a[$1] || !a[$1]){a[$1]=$2}END{for(f in a){print f,a[f]}}' file
Orange 2
Banana 1
Apple 3
a[$1]=$2
a
キーが最初のフィールドで値が2番目のフィールドである配列を設定します。上記のスクリプトは、i)保存された値より小さい、またはii)保存された値がない場合、2番目のフィールドを配列の最初のフィールド値として保存します。このEND
ブロックは配列を繰り返し、その内容を印刷します。
GNUの使用sort
:
$ sort -nk2 file | sort -u -k1,1
Apple 3
Banana 1
Orange 2
最初のソートは、重みの昇順で行を印刷します(2番目のフィールド)。 2番目のソートは一意の行のみを維持し、最初のフィールドのみをチェックします。結果は各文字列の最初の項目を印刷することであり、最初のソートのためにその果物の最小値になります。
Perlの(少し)短いバージョンもあります:
$ perl -lane '$k{$F[0]}//=$F[1]; $k{$F[0]}=$F[1] if $F[1]<$k{$F[0]};
END{print "$_ $k{$_}" for keys(%k)}' file
Orange 2
Apple 3
Banana 1
//=
変数にすでに値がない場合は、値が割り当てられます。次の方法はawk
上記と同じです。キーがフルーツで値が重み付けされたハッシュを生成し、%k
最小値を保存します。この-a
フラグは、空白の入力を配列に分割するのperl
と同じように機能します。awk
@F
答え3
Perl onelinerを使用してこれを行うことができます。
perl -ane '$h{$F[0]} = $F[1] if (!defined $h{$F[0]} || $h{$F[0]} > $F[1]);
END {foreach (keys %h) {print "$_ $h{$_}\n"}}' fruits_list.txt
ここでは、ハッシュマップ(%h)を使用して要素を保存します。果物がハッシュにまだ存在しない場合は最初の値を追加し、存在する場合はすでに保存されている値より小さい場合にのみ値を更新します。 ENDブロックはファイルの最後の行を処理した後にのみ実行され、ハッシュマップを印刷します。
答え4
sort -k2,2n file | sort -u -k1,1
出力:
iPhone 3 バナナ1 オレンジ2