2012-05-26 81 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:好主意 - 完成。 –