Bash按两个键对数组进行排序

时间:2014-03-22 09:41:22

标签: arrays bash sorting

我需要用两个键对数据进行排序,得分和按字母顺序排列。

例如:

arr = (Hawrd 60 James 75 Jacob 60 Leonard 75) 

将成为:

sorted = (Hawrd 60 Jacob 60 James 75 Leonard 75)

*实际上我不需要排序的数组,只需要打印它(以名称和分数的格式)。谢谢! *我读到了命令排序,但我看不出如何使用该命令按两个键排序

编辑:对不起,如果它不清楚,但我的意思是每个人都有自己的分数,伦纳德有75分,雅各有60分,在这个过程的最后,每个人仍然会有相同的分数

3 个答案:

答案 0 :(得分:1)

这是一种方法:

arr=( Hawrd 60 James 75 Jacob 60 Leonard 75 )

#first we sort the array like this: 60 60 75 75 Hawrd James Jacob Leonard
OLDIFS=$IFS
IFS=$'\n' arr_sorted=($(sort <<<"${arr[*]}"))
IFS=$OLDIFS

#second, we split the sorted array in two: numbers and names
cnt="${#arr_sorted[@]}"
let cnt1="$cnt/2"
let cnt2="$cnt - $cnt1"
nr_sorted=( "${arr_sorted[@]:0:$cnt1}" )
names_sorted=( "${arr_sorted[@]:$cnt1:$cnt2}" )

#and third, we combine the new arrays(names ang numbers) element by element
for ((i=0;i<${#names_sorted[@]};i++)); do sorted+=(${names_sorted[i]} ${nr_sorted[i]});done

#now the array 'sorted' contain exactly what you wished; let's print it
echo "${sorted[*]}"

答案 1 :(得分:1)

我不确定这是否能回答这个问题,但提供的这些细节我会尝试

这是一个解决方案:

 [ ~]$ cat test.sh 
 #!/bin/bash

 declare -a array
 declare -a ageArray
 array=("Hawrd 60" "James 75" "Jacob 60" "Leonard 75")
 size=${#array[@]}

 for (( i=0 ; i < $size ; i++ )); do
     age=$(echo "${array[$i]}"|egrep -o "[0-9]*")
     ageArray[$i]="$age_${array[$i]}"
 done

 # sorting by age and by name (with ascii comparison)
 for (( i=0 ; i < $size ; i++ )); do
     for (( j=$i+1 ; j < $size ; j++ )); do
         if [[ ${ageArray[$j]} < ${ageArray[$i]} ]]; then
             tmp="${array[$i]}"
             ageTmp="${ageArray[$i]}"

             array[$i]="${array[$j]}"
             ageArray[$i]="${ageArray[$j]}"

             array[$j]="$tmp"
             ageArray[$j]="$ageTmp"
         fi
     done 
 done

 #printing result
 for item in "${array[@]}"; do
     echo "$item"
 done
 [ ~]$ ./test.sh 
 Hawrd 60
 Jacob 60
 James 75
 Leonard 75

答案 2 :(得分:0)

如果你不介意Perl,你可以这样做:

#!/bin/bash
arr=(Zigbee 9 Hawrd 60 Apple 99 James 75 Jacob 60 Leonard 75) 
echo -n ${arr[@]} | perl -040 -nE 'if(defined($a)){push(@l,{Name=>$a,Score=>$_});undef $a}else{$a=$_};END{foreach(sort {$$a{Score} <=> $$b{Score} or $$a{Name} cmp $$b{Name}} @l){say "$$_{Name} $$_{Score}"}}'

通过使Perl的记录分隔空间(-040),回显数组的元素并一次读取每个元素。一个名称读入$ a,然后在下一次读取时,定义为$ a id,下一个值在$ b中读取。然后将$ a和$ b推送到哈希数组的末尾。最后(END),数组按分数和名称排序,并打印出名称和分数。

<强>输出:

Zigbee 9
Hawrd 60
Jacob 60
James 75
Leonard 75
Apple 99