Inversão dos pares de chaves de valor da matriz usando substituição de sed ou padrão ou expansão de contraventamento?

1
#!/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 sed ou qualquer outro comando. Eu acho que teria que apenas fazer alguma mudança de padrão de texto em vez de usar loops bash , talvez algo como.

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

para que o novo array se torne como brr=([a]=0 [b]=1 [c]=2 [d]=3) se eu usar a expansão de contraventamento, 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 : Eu consegui fazê-lo, mas posso torná-lo mais curto e simples, especialmente as sed lines

#!/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,\}\)\(.*\)/$(echo  - 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
    
por munish 06.10.2013 / 08:25

3 respostas

4

Eu prestaria atenção ao conselho do @ ChrisDown e não tentaria fazer algo inteligente aqui. Gostaria de criar o loop for e inverter as chaves com os valores na nova matriz. São apenas algumas linhas de código.

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

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

ou

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

Saída:

#arr['a']=0 arr['b']=1 arr['c']=2 arr['d']=3
    
por 11.10.2013 / 18:35
0

Como outros já disseram, acho que sed seria 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
    
por 13.10.2013 / 05:34