Revertendo os pares de chaves de valor da matriz usando sed ou substituição de padrão ou expansão de chaves?

Revertendo os pares de chaves de valor da matriz usando sed ou substituição de padrão ou expansão de chaves?
#!/bin/bash
arr=(a b c d)
declare -A brr
for i in ${!arr[@]}
do
  brr[${arr[$i]}]=$i
done
echo ${brr[@]}                             #0 1 2 3

Existe alguma maneira de reverter os valores e pares de chaves usando sedou qualquer outro comando. Eu acho que eu teria que apenasfaça alguma mudança de padrão de texto em vez de usar loops bash, talvez algo parecido.

brr=($(echo ${!arr[@]} | sed commands))

para que o novo array fique como brr=([a]=0 [b]=1 [c]=2 [d]=3) se eu usasse a expansão de chaves, ele pode chegar a este ponto:

#!/bin/bash
arr=(a b c d)
declare -A brr
var=${arr[@]}
var=${var// /,}
brr=$(eval echo [{$var}]=)
echo $brr                              #[a]= [b]= [c]= [d]=

agora só preciso adicionar as chaves 0,1,2,3

EDITAR: Consegui fazer isso, mas posso torná-lo mais curto e simples, especialmente as sedlinhas

#!/bin/bash
arr=(a b c d)
declare -A Rev
var=${arr[@]}                    #var is equal to a b c d
var=${var// /,}                  #var is equal to a,b,c,d after adding , for space
brr=$(eval echo Rev[{$var}]=)    #brr equal to Rev[a]= Rev[b]= Rev[c]= Rev[d]=

#NOW I NEED TO CHANGE 
#Rev[a]= Rev[b]= Rev[c]= Rev[d]=
#to
#Rev['a']=0;Rev['b']=1;Rev['c']=2;Rev['d']=3

r="$(echo $brr | 
sed 's/ /\n/g' | sed '/./=' | sed '/./N; s/\n//' | 
  sed 's/\(^[0-9]\{1,\}\)\(.*\)/\2$(echo \1 - 1 | bc)/' | tr '\n' ';' |
                                                          sed "s/\[/\[\'/g;s/\]/\'\]/g")"
#pipe the output of echo(Rev[a]= Rev[b]= Rev[c]= Rev[d]=) to sed
#convert space to newlines
#add line numbers
#put the line numbers adjacent to the values Rev[a],Rev[b],Rev[c],Rev[d] like
# 1rev[a]=
# 2Rev[b]=
# 3Rev[c]=
# 4Rev[d]=
#change 1Rev[a]= format to Rev[a]=1
#convert newlines to ; looking like Rev[a]=0;Rev[b]=1;Rev[c]=2;Rev[d]=3
#put quotes around the keys Rev['a']=0;Rev['b']=1;Rev['c']=2;Rev['d']=3

eval $r
echo ${Rev[@]}      #0 1 2 3
echo ${!Rev[@]}     #a b c d

Responder1

Eu seguiria o conselho de @ChrisDown e não tentaria fazer algo inteligente aqui. Eu criaria o loop for e inverteria as chaves com os valores do novo array. São apenas algumas linhas de código.

Qualquer coisa que você criar dessa maneira será mais difícil para outros apoiarem no futuro e mais difícil para você lembrar/entender como funciona quando revisitar o código no futuro.

Responder2

#!/bin/bash
arr=(a b c d)
set -- $(echo ${arr[@]} | tr ' ' '\n' | sed "s/.*/arr['&']=/")
eval echo $(seq 1 ${#arr[@]} | sed 's/\(.*\)/${\1}$(echo \1 -1 | bc)/') 

ou

#!/bin/bash
declare -A brr
arr=(a b c d)
eval "brr=($(eval echo $(sed 's/\([0-9]\)/[${arr[\1]}]=\1/g' <(echo ${!arr[@]}))))"
echo ${brr[@]}

Saída:

#arr['a']=0 arr['b']=1 arr['c']=2 arr['d']=3

Responder3

Como outros já disseram, acho que sedseria uma solução difícil.

O loop a seguir pode realizar o que você deseja:

arr=(a b c d)
for i in ${!arr[@]}; do
    brr+=("[${arr[$i]}]=$i")
done
echo ${brr[@]}
#[a]=0 [b]=1 [c]=2 [d]=3

informação relacionada