Umkehren der Wert-Schlüsselpaare des Arrays mittels sed oder Musterersetzung oder Klammernerweiterung?

Umkehren der Wert-Schlüsselpaare des Arrays mittels sed oder Musterersetzung oder Klammernerweiterung?
#!/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

Gibt es eine Möglichkeit, die Werte und Schlüsselpaare mit sedoder einem anderen Befehl umzukehren? Ich denke, ich müsste einfachNehmen Sie einige Musteränderungen am Text vor, anstatt Bash-Schleifen zu verwenden, vielleicht so etwas wie.

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

sodass das neue Array so aussieht, brr=([a]=0 [b]=1 [c]=2 [d]=3) als würde ich die Klammererweiterung verwenden, es kann bis zu diesem Punkt reichen:

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

jetzt muss ich nur noch die Schlüssel 0,1,2,3 hinzufügen

BEARBEITEN: Ich habe es geschafft, aber kann ich es kürzer und einfacher machen, insbesondere die sedZeilen

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

Antwort1

Ich würde den Rat von @ChrisDown beherzigen und hier nicht versuchen, etwas Schlaues zu machen. Ich würde die For-Schleife erstellen und die Schlüssel mit den Werten im neuen Array vertauschen. Es sind nur ein paar Zeilen Code.

Alles, was Sie auf diese Weise erstellen, wird für andere später schwieriger zu unterstützen sein und für Sie wird es schwieriger sein, sich daran zu erinnern/zu verstehen, wie es funktioniert, wenn Sie den Code in Zukunft erneut aufrufen.

Antwort2

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

oder

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

Ausgabe:

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

Antwort3

Wie andere bereits gesagt haben, glaube ich, dass seddies eine schwierige Lösung wäre.

Die folgende Schleife könnte Ihr Ziel erreichen:

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

verwandte Informationen