2012-05-26 80 views
0

如何在bash中將「python字典樣式」數組e.g. ("A: 2" "B: 3" "C: 1")按值排序?我認爲,這段代碼將使我的問題更加清晰。在bash中對「鍵/值對」數組進行排序

State="Total 4 0 1 1 2 0 0" 
W=$(echo $State | awk '{print $3}') 
C=$(echo $State | awk '{print $4}') 
U=$(echo $State | awk '{print $5}') 
M=$(echo $State | awk '{print $6}') 
WCUM=("Owner: $W;" "Claimed: $C;" "Unclaimed: $U;" "Matched: $M") 
echo ${WCUM[@]} 

這將簡單地打印數組:Owner: 0; Claimed: 1; Unclaimed: 1; Matched: 2

如何陣列(或輸出)進行排序,從而消除了任何對用「0」值時,使得結果是這樣的:

Matched: 2; Claimed: 1; Unclaimed: 1 

在此先感謝您的任何幫助或建議。乾杯!!

+0

你在排序什麼,「匹配」? – John3136

+1

使用python會是我的建議!恕我直言,你已經離開了bash的甜蜜點。 –

+0

@ NickCraig-Wood:顯然你不知道bash。 –

回答

2

快速和骯髒的想法是(這只是排序輸出,而不是數組):

echo ${WCUM[@]} | sed -e 's/; /;\n/g' | awk -F: '!/ 0;?/ {print $0}' | sort -t: -k 2 -r | xargs 
+0

感謝Michał,它工作得很好。排序數組或輸出 - 無論哪種方式適用於我。我需要打印格式化結果。乾杯!! – MacUsers

0

的另一種嘗試,使用一些的bash特性,但仍然需要排序,這是至關重要的:

#! /bin/bash 
State="Total 4 1 0 4 2 0 0" 
string=$State 
for i in 1 2 ; do  # remove unnecessary fields 
    string=${string#* } 
    string=${string% *} 
done 

# Insert labels 
string=Owner:${string/ /;Claimed:} 
string=${string/ /;Unclaimed:} 
string=${string/ /;Matched:} 

# Remove zeros 
string=(${string[@]//;/; }) 
string=(${string[@]/*:0;/}) 
string=${string[@]} 

# Format 
string=${string//;/$'\n'} 
string=${string//:/: } 

# Sort 
string=$(sort -t: -nk2 <<< "$string") 
string=${string//$'\n'/;} 
echo "$string" 
1
echo -e ${WCUM[@]} | tr ';' '\n' | sort -r -k2 | egrep -v ": 0$" 

排序和過濾是獨立的步驟,所以如果你只喜歡過濾0值,它會更容易些。

追加的

| tr '\n' ';' 

它到底又得到一個單行。

nonull=$(for n in ${!WCUM[@]}; do echo ${WCUM[n]} | egrep -v ": 0;"; done | tr -d "\n") 

我沒有看到一個很好的理由來結束$ W $ C $ U用分號,但$ M沒有,所以反而適應我的代碼這種區別我想消除這種特殊情況。如果不行的話,我會將一個分號臨時添加到$ M中,並最終刪除它。

+0

就「分號」事達成一致;這是第一個版本,我仍然在決定要做什麼。感謝代碼 - 我實際上有一個想法在別處使用它。只有一件事:'seq'部分可以像這樣縮短:'$ {!WCUM [@]}'。乾杯!! – MacUsers

+0

@MacUsers:好主意 - 完成。 –