2017-04-16 68 views
2

在使用bash的shell腳本中,我想查找數組中最常出現的數字,並將結果存儲在變量$ result中。該數組可以有任意數量的值。如果返回多個結果,那麼我想選擇最低的數字。數組中最常見的元素(bash 3.2)

我知道bash可能不是最好的工具,因此我願意使用Mac OS X系統上的腳本中的命令行提供的工具。

實施例:

陣列=(03 03 03 04 04 04 04)
3出現的03
4出現的04
應該返回04到一個變量名爲$結果。

又如:

陣列=(03 03 03 03 04 04 04 04)
出現4次的03
出現4次的04
選擇最低數目是03
應返回03放入名爲$ result的變量中。

謝謝你的幫助。

+0

我不確定這是否會對這個特定問題有所幫助。我不是一個bash大師或任何東西。但無論如何,你可以通過[Homebrew](https://brew.sh/)輕鬆獲得更新版本的bash。我相信最新版本是4.4。新版本提供了許多其他有用的功能。 –

回答

2

下面是一個基於AWK的解決方案,避免了慶典,關聯數組:

#!/bin/bash 
get_result(){ 
awk ' 
    { 
     n=++hsh[$1] 
     if(n>max_occ){ 
     max_occ=n 
     what=$1 
     }else if(n==max_occ){ 
     if(what>$1) 
      what=$1 
     } 
    } 
    END { print what } 
' 
} 

array=(03 03 03 04 04 04 04) 
result=$(printf "%s\n" "${array[@]}" | get_result) 
echo $result 

array=(03 03 03 03 04 04 04 04) 
result=$(printf "%s\n" "${array[@]}" | get_result) 
echo $result 

的結果是03和04在你的榜樣。

0

您可以使用關聯數組,讓您的數組元素的頻率的軌跡:

#!/bin/bash 

arr=(1 2 3 4 4 44 4 4 5 5) 
declare -A hash 
max_times=0 
for i in "${arr[@]}"; do 
    ((hash[$i]++)) 
    h=${hash[$i]} 
    if [[ $h > $max_times ]]; then 
    max=$i 
    max_times=$h 
    fi 
done 

echo max=$max, max_times=$max_times 

輸出:

max=4, max_times=4 

如果我們不能使用關聯數組,那麼我們就可以使使用外部工具:

array=(1 3 3 333 5 66 5 33 66 66 33 22 11) 
printf '%d\n' "${array[@]}" | sort -n | uniq -c | sort -n | tail -1 

輸出:

3 66 
+0

感謝您的回覆,不幸的是我只有bash 3.2可用,並且不希望在Mac OS X上升級bash。據我所知,bash版本中的declare函數不可用<4.0 – KeelDev

+0

uniq行不會與第二個數組一起工作。 – PSkocik

+0

@KeelDev'declare'本身比Bash 4.0早,但關聯數組的'declare -A'是4.0或更新。 –

2

有一個在你的問題的不確定性,其需要解決:你說的數組是數字的數組,但例如會呈現前導零,如果你把字符串作爲這將導致一些驚喜數字(他們將被解釋爲八進制)。

除此之外,解決方案相對簡單:使用sortuniq來計算每個值的實例數,按count排序結果,然後提取第一個值。爲了滿足這類要求,我們開始使用printf每行數組一個元素寫着:

printf '%s\n' "${arr[@]}" | sort | uniq -c | 
sort -k1,1nr -k2 | awk '{print $2; exit}' 

兩個調用到sort排序原始數據爲字符串。如果你真的想給他們排序爲數字,你可以使用:

printf '%d\n' "${arr[@]}" | sort -n | uniq -c | 
sort -k1,1nr -k2n | awk '{print $2; exit}' 

儘管這將正常化所有數字的規範形式(使03將成爲3)。

+0

這不適用於 - > arr =(03 03 03 04 04 04 04) – KeelDev

+0

@keelDev:在這個答案中有三個建議,你沒有指定哪一個不起作用,但是由於printf錯誤(也更嚴重的是,使用uniq),它一定是最後一個。所以我刪除了它;另外兩個在它們各自的限制內正常工作(將數據視爲字符串或規範化數字)。 – rici