2012-04-11 13 views
0

Ich habe ein Bash-Skript, das einige Sätze erstellen muss, die jeweils 1 Element aus mehreren Warteschlangen enthalten (ich überlege, Arrays zu verwenden, um diese zu speichern) Zum Beispiel wenn ich die folgenden Warteschlangen habe:Zugriffsbereich des indirekt referenzierten Arrays in Bash

array1=(a b c e f)                
array2=(x y z)                 
array3=(1 2 3 4) 

ich brauche die folgenden Arrays zu erhalten (nicht notwendigerweise alle auf einmal, i verarbeiten, um die resultierenden Arrays einen nach dem anderen)

 
a x 1 
b y 2 
c z 3 
e 4 
f 

Die Anzahl der Arrays dynamisch ist.

Also im Grunde muss ich das erste Element aus jedem Array und ein anderes Array einfügen. Ich weiß, dass ich das erste Element aus einem Array wie folgt Pop kann:

el1=${array1[0]} 
array1=(${array1[@]:1:$((${#array1[@]}))}) 

Auch ich weiß, ich einen Wert aus einem indirekt referenzierten Array wie folgt extrahieren:

val=$(eval echo \${$arr[0]}) 

Meine Frage ist, : Wie kann ich den Teil, der das erste Element aus einem Array öffnet, neu schreiben, um indirekte Referenzen zu verwenden.

Hier ist der vollständige Testskript:

#!/bin/bash 

set -e 
set -u 


array1=(a b c e f) 
array2=(x y z) 
array3=(1 2 3 4) 

finished=false 
while ! $finished; do 
    finished=true 

    array4=() 
    for arr in array1 array2 array3; do 
     val=$(eval echo \${$arr[0]}) 
     if [ ! -z $val ]; then 
     array4=(${array4[@]} $val) 
     $arr=(\${$arr[@]:1:$((\${#$arr[@]}))}) 
     fi 
    done 

    l4=${#array4[@]} 
    if [ $l4 -gt 0 ]; then 
     finished=false 

     for i in ${array4[@]}; do 
     echo $i 
     done 
    fi 

done 

Antwort

1
array1=(a b c e f)                
array2=(x y z)                 
array3=(1 2 3 4) 

cnt=0 
while : ; do 
    line='' 
    for a in ${!array*}; do    # loop over names "array*" 
    val=$(eval echo \${$a[$cnt]}) 
    line="$line ${val:- }"    # build line 
    done 
    ((cnt++)) 
    [[ $line =~ ^\ +$ ]] && break   # break if line has only blanks 
    echo -e "${line:1}" 
done 

Ausgang:

a x 1 
b y 2 
c z 3 
e 4 
f  
+0

Thanks.I schließlich herausgefunden ich stattdessen einen Index verwenden könnte versuchen, Elemente Pop. Aber ich wusste nichts über die Konstrukte $ {! Array *} und ((cnt ++)). – MasterF

Verwandte Themen