¿Invertir los pares de claves de valor de la matriz usando sed o reemplazo de patrón o expansión de llaves?

¿Invertir los pares de claves de valor de la matriz usando sed o reemplazo de patrón o expansión de llaves?
#!/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

¿Hay alguna forma de revertir los valores y los pares de claves usando sedcualquier otro comando? Creo que tendría que simplementehacer algún cambio de patrón de texto en lugar de usar bucles bash, quizás algo así como.

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

para que la nueva matriz se vuelva como brr=([a]=0 [b]=1 [c]=2 [d]=3) si uso la expansión de llaves, puede llegar a este punto:

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

ahora solo necesito agregar las claves 0,1,2,3

EDITAR: Pude hacerlo pero ¿puedo hacerlo más corto y simple, especialmente las sedlíneas?

#!/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

Respuesta1

Seguiría el consejo de @ChrisDown y no intentaría hacer algo inteligente aquí. Crearía el bucle for e invertiría las claves con los valores en la nueva matriz. Son sólo unas pocas líneas de código.

Cualquier cosa que cree de esta manera será más difícil de soportar para otros en el futuro, y más difícil para usted recordar/comprender cómo funciona cuando revise el código en el futuro.

Respuesta2

#!/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)/') 

o

#!/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[@]}

Producción:

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

Respuesta3

Como han dicho otros, creo que sedsería una solución difícil.

El siguiente bucle podría lograr lo que desea:

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

información relacionada