Bashでリスト(入れ子になったリスト)を繰り返すには?

Bashでリスト(入れ子になったリスト)を繰り返すには?

次のリストがあります。

data = [ ['a', 'b' ], ['a1', 'b1'], ['c1', 'd1' ] ]

各ネストされたリストの2つの要素を同時に繰り返してアクセスしたいと思います。

それは次のとおりです。

for elements in ??
do
    python3 main.py --argument1 elements[0] --arguments2 elements[1]
done

入れ子になったリストの各要素にどのようにアクセスしますか?

私はこれを試しました:

a1=( a a1 c1 )
a2=( b b1 d1 )

declare -i i=0

while [ "${a1[i]}" -a "${a2[i]}" ]; do

    printf " %s  %s\n" "${a1[i]}" "${a2[i]}"
    ((i++))

done

exit 0

答え1

にはリストリストのようなものがないので、コードがbash示すように、ループ内の2つのリストをペアで繰り返そうとします。さらに、両方のリストは常に同じ数の要素を含み、リストがリーンではないと仮定する。

インデックスまたは要素自体を使用して、繰り返しループを作成できます。

次の例は、配列の1つのインデックスを繰り返し、それを使用して2つの配列の要素にアクセスする方法を示しています。

a1=( a a1 c1 )
a2=( b b1 d1 )

for i in "${!a1[@]}"; do
        printf 'Pair: (%s,%s)\n' "${a1[i]}" "${a2[i]}"
done

式は"${!a1[@]}"配列インデックスを含むリストに展開されますa1

ループ内で直接配列要素を使用することもできます。

a1=( a a1 c1 )
a2=( b b1 d1 )

set -- "${a1[@]}"

for b in "${a2[@]}"; do
        a=$1; shift
        printf 'Pair: (%s,%s)\n' "$a" "$b"
done

ここでは、位置引数のリストをa1配列の要素に設定しsetてから、他の配列の要素を繰り返します。値は$bループの要素で、最初の位置引数(次の要素)です。値は、位置パラメータリストで指定された次の位置パラメータリストから削除されます。a2$1a1$1a

上記の両方のコードは同じ出力を生成します。

Pair: (a,b)
Pair: (a1,b1)
Pair: (c1,d1)

表示されるコードの主な問題は、空の要素が見つかったときに配列の終わりに達したかどうかわからないことです。配列には空の要素を許可する必要があります。あいまいな可能性があるため、-a構文の内部を避けてwithに置き換えるのが最善です。withが空でない文字列であることもテストする必要があります。[ ... ][ ... ] && [ ... ]-n

答え2

データとarrnumを変更するときは、目的に合わせて多次元配列を使用できます。

data=( a b a1 b1 c1 d1 )
arrnum=2
len=${#data[@]}

declare -i i=0

while [ "$len" -gt "$((i*arrnum))" ]; do

    for (( j=0; j<$arrnum-1; j++ )); do
    printf " %s  " "${data[i*arrnum+j]}"
    done
        printf " %s\n" "${data[i*arrnum+j]}"
    
    ((i++))

done

exit 0

結果:

1

関連情報