2012-12-03 42 views
2

我有此數組:Bash-總和從一行值的數組

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次)。有任何想法嗎?

回答

3

使用AWK:

$ printf "%d\n" "${array[@]}" | sort -nr | awk 'NR>1 && p!=$0{print x;exit;}{x+=$0;p=$0;}' 
12 

使用類別,數量也以相反的(-R)順序排序(-n),並且保持AWK直到它找到一個數,其是來自不同的數字求和前一個。

+0

感謝一位大師,大大提供幫助! – teutara

+0

+1。哈,當然,我以爲你會需要兩個循環,但因爲它已經倒過來排序幾乎微不足道:) –

2

你可以用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[@]}"是一個在這裏的文檔,它允許你將一個字符串(在這個例子中是數組的所有元素)作爲標準輸入到awk

這種方式不涉及管道或循環 - 一個命令完成所有工作。

+0

+1,很好的使用awk的'RS'。你可以通過將if條件移動到一個新的分支來保存幾個字符:'{sum [$ 0] + = $ 0} $ 0> max {max = $ 0}' –

+0

@glennjackman是的,但這是SO,不是代碼高爾夫。 :) –

5
dc <<<"$(printf '%d\n' "${array[@]}" | sort -n | uniq -c | tail -n 1) * p" 
  1. sort在年底獲得最大的價值
  2. uniq -c獲得唯一的值,與他們有多少次出現
  3. tail計數只得到最後一行(與最大值和它的計數)
  4. dc到由計數相乘的值

我選擇dc作爲乘法步驟,因爲它是RPN,因此您不必拆分uniq -c輸出並在其中間插入任何東西 - 只需添加內容即可。

+0

awesoem馬克裏德,謝謝! – teutara

+1

+1只是因爲你使用了'dc'而且我喜歡它! –

+0

+1不使用其他語言的柺杖 – Sorpigal

-1

只使用bash下

echo $((${array// /+})) 

Replace所有空格用加,並使用double-parentheses表達評估。

+0

這並不回答這個問題,即使我發現你的方法很酷。另外它不適合我。 但是'echo $(printf「%d +」$ {speeds [@]})0 | BC'做了訣竅。 – Titou