使用 sed 或模式替換或大括號擴展反轉數組的值鍵對?

使用 sed 或模式替換或大括號擴展反轉數組的值鍵對?
#!/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

sed有沒有辦法使用或任何其他命令來反轉值和密鑰對。我想我必須只是對文字進行一些模式更改,而不是使用 bash 循環,也許類似。

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

這樣新數組就像brr=([a]=0 [b]=1 [c]=2 [d]=3) 我使用大括號擴展一樣,它可以達到這一點:

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

現在我只需要添加鍵 0,1,2,3

編輯:我能夠做到,但是我可以讓它更短更簡單,尤其是sed線條

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

答案1

我會聽取@ChrisDown 的建議,而不是嘗試在這裡做一些聰明的事情。我將建立 for 迴圈並使用新陣列中的值反轉鍵。只需幾行程式碼。

您以這種方式創建的任何內容都將更難讓其他人在以後支持,並且當您將來重新訪問程式碼時,您將更難記住/理解它是如何工作的。

答案2

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

或者

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

輸出:

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

答案3

正如其他人所說,我認為sed這將是一個困難的解決方案。

下面的循環可以完成你想要的:

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

相關內容