私はこの配列を持っています:
array=(1 2 3 4 4 3 4 3)
次の方法で最大数を取得できます。
echo "num: $(printf "%d\n" ${array[@]} | sort -nr | head -n 1)"
#outputs 4
しかし、私はすべての 4 の合計を取得したいので、代わりに 12 (4 が 3 回出現) を出力したいと考えています。何か案は?
dc <<<"$(printf '%d\n' "${array[@]}" | sort -n | uniq -c | tail -n 1) * p"
sort
最後に最大値を取得するuniq -c
出現回数をカウントして、一意の値のみを取得するtail
最後の行のみを取得する (最大値とそのカウントを含む)dc
値にカウントを掛けるdc
RPN であるため、乗算ステップを選択したため、uniq -c
出力を分割して途中に何かを挿入する必要はありません。最後に何かを追加するだけです。
awk の使用:
$ printf "%d\n" "${array[@]}" | sort -nr | awk 'NR>1 && p!=$0{print x;exit;}{x+=$0;p=$0;}'
12
sort を使用すると、数字は逆順 (-r) にソート (-n) され、awk は前の数字とは異なる数字が見つかるまで数字を合計し続けます。
あなたはこれを行うことができますawk
:
awk -v RS=" " '{sum[$0]+=$0; if($0>max) max=$0} END{print sum[max]}' <<<"${array[@]}"
(レコード区切り文字) をスペースに設定RS
すると、配列エントリを個別のレコードとして読み取ることができます。
sum[$0]+=$0;
手段sum
は、各入力値の累積合計のマップです。if($0>max) max=$0
これまでに見た最大数を計算します。END{print sum[max]}
最後に見られる最大数の合計を出力します。
<<<"${array[@]}"
は、文字列 (この場合は配列のすべての要素) を stdin として にフィードできるようにするヒアドキュメントですawk
。
この方法では、パイピングやループは必要ありません。単一のコマンドですべての作業が行われます。