Having an array of this type:

declare -A ARRAY ARRAY[0,0]=число ARRAY[0,1]='строка' ARRAY[1,0]=число ARRAY[1,1]='строка' # ... ARRAY[$N,0]=число ARRAY[$N,1]='строка' 

It is necessary to sort it by numbers (in reverse order, but I think it does not matter) and get only a list of strings. That is, with such data:

 [ 1, 'd' ] [ 4, 'a' ] [ 2, 'c' ] [ 3, 'b' ] 

The output should be:

 [ 'a','b','c','d' ] 

While the head climbs completely stupid:

 DATA="" for(( i = 0; i < $N; i++ )); do DATA+="${ARRAY[$i,0]} ${ARRAY[$i,1]}"$'\n' done echo "$DATA" | sort -gr | sed -e 's/^[0-9 ]*//g' 

But for some reason it does not seem like the best option :)

  • specify what you need to get as a result. - aleksandr barakin
  • @alexanderbarakin, "get only a list of strings" - PinkTux

2 answers 2

On a clean bash , somehow, but I'm not sure if this is better.

 #!/bin/bash declare -A ARRAY ARRAY[0,0]=5 ARRAY[0,1]='строка3' ARRAY[1,0]=2 ARRAY[1,1]='строка10' ARRAY[2,0]=12 ARRAY[2,1]='строка8' declare -a HASH N=3 for (( i = 0; i < $N; i++ )); do HASH[${ARRAY[$i,0]}]=${ARRAY[$i,1]} done RES= for i in ${!HASH[@]}; do RES="${HASH[$i]} $RES" done echo $RES 

No sort , sed , other bash launches, thread redirection are applied.

At the output of the test case:

line8 line3 line10

  • ${!HASH[@]} - there will be a non-numeric sort. and, for example, 10 will be "less" 2 . - aleksandr barakin
  • @alexanderbarakin, are you on the index or the number in string version? And yes, just run. I'll add the output now. - 0andriy
  • ${!HASH[@]} - returns a sorted list of indexes. in my tests, sorting was not based on numeric values ​​(because I refused this approach). this was probably due to the presence of strings in the test array. - aleksandr barakin
  • @alexanderbarakin, just often do not read the documentation carefully. In fact, the script names are incorrect: ARRAY in fact hash, and HASH is an array. That's the difference in the output. Accordingly, it is easy to see that the internal representation of the hash is a tree. - 0andriy
  • one
    It is better in performance and lack of external dependencies at a minimum. Just not very clear. - PinkTux

the approach is, in general, the only possible one: get the values ​​from the required “column” and their indices, sort the list by these values, discard values, and get the values ​​from another “column” by indices.

your option can only be optimized a little by instructing “dropping” the bash program itself (and thus excluding the additional program call sed ):

 #!/bin/bash declare -A array array[0,0]=1 array[0,1]='d' array[1,0]=4 array[1,1]='a' array[2,0]=2 array[2,1]='c' array[3,0]=3 array[3,1]='b' n=3 data=() while read n garbage; do data+=(${array[$n,1]}); done < <(for i in $(seq 0 $n); do echo $i ${array[$i,0]}; done | sort -k 2rn) echo ${data[@]} 

design

 while read ... < <(for ... | sort ...) 

used instead of "obvious"

 for ... | sort ... | while read ... 

due to the fact that when using a “pipeline” ( pipe , | ) a new instance of the shell is created, and the change of the local variable (in this case, data ) is “not visible” in the main instance of the shell.

  • But here instead of sed appears seq :) In fact, this is not so scary, in the whole script there are things much harder (for example, find thousands of files) ... Just the general principles and possible approaches were not entirely clear. - PinkTux
  • Well, if we are talking about general principles, it is better, of course, to get rid of the pseudo-multidimensional array first. and store the strings in an "ordinary" array: a[число]="строка" . manipulations immediately greatly simplified. - aleksandr barakin
  • It will not work, the numbers may be non-unique. Especially since initially they are all 0 , and the values ​​are finally formed in the process of any manipulations before sorting. Here are the lines - unique, they can be used as keys. But then how to sort by numeric values ​​is not very thought. - PinkTux
  • And after: and bash guarantees the preservation of the bypass order of such a hash in the loop for var in ... ? No matter what exactly will be the key. And how to get the item following the current one? - PinkTux
  • one
    1. nonunique numbers is a very significant point, by the way. because of it, the solution with the intermediate array proposed in the adjacent answer seems to give you not exactly what is expected. 2. sort - in the same way. 3. stackoverflow.com/a/29161460/4827341 - aleksandr barakin