1つの変数に複数のデータ項目を割り当てることはできますか?それでは、どのように配布されますか?

1つの変数に複数のデータ項目を割り当てることはできますか?それでは、どのように配布されますか?

私はLinux Bash / Shellを使用しており、複数の個々のデータ項目を変数に割り当てる方法を知りたいです。

たとえば、チームのリストです。各チームが求めるデータは、ホームマッチ総得点-遠征競技総得点-ホーム競技総得点-遠征競技総得点等である。

答え1

シェルはbash単一の汎用変数に個々の文字列を格納し、配列に文字列のリストを格納し、関連配列に他の文字列に関連付けられた文字列を格納できます。たとえば、配列の配列または関連配列の関連配列(またはそれらの組み合わせ)を保存することはできません。

あなたが言及した特定のデータについては、できる連想配列などの操作を実行します。

declare -A goals

goals["teamA"]="0:2:3:4"
goals["teamB"]="1:3:3:3"
# etc.

または

declare -A goals

goals=(
    ["teamA"]="0:2:3:4"
    ["teamB"]="1:3:3:3"
    # etc.
)

次に、:必要に応じて分離された値を解析します。

for team in "${!goals[@]}"; do
    home_goals=$( cut -d : -f1 <<<"${goals[$team]}" )
    away_goals=$( cut -d : -f2 <<<"${goals[$team]}" )
    # etc.

    # use "$team", "$home_goals", "$away_goals" etc. here
done

...しかしそうです。たくさんこれはPerlやPythonなどの言語を使用してより効率的に実行できます。する任意にネストされたデータ構造が許可されます。

たとえば、Perlでは次のようになります。

my %goals = ( "teamA" => [ 0, 2, 3, 4 ],
              "teamB" => [ 1, 3, 3, 3 ],
              # etc.
            );

答え2

私が知っているシェルには入れ子になったデータ構造がないので、このような構造化データをうまく処理できません。 (ここにはタグ付き Bash が含まれます。) オブジェクトのリストや C スタイルの構造が必要ですが、持っているのは配列と関連配列だけです。

1つの方法は、保持している各データ(得点、失点...)ごとに別々の連想配列を作成し、チーム名別に配列を入力することです。

例えば

declare -A goals_scored goals_conceded
goals_scored[Liverpool]=4
goals_conceded[Liverpool]=2
goals_scored[Tottenham]=3
goals_conceded[Tottenham]=3
for team in "${!goals_scored[@]}"; do       # iterate over the keys of goals_scored
    echo "$team has scored ${goals_scored[$team]} goals"
done

データ項目が最上位レベルにあり、たとえばプレーヤーの構造もあると混乱し始めるため、これは少し見苦しいです。 (たとえば、goals_scoredチームや選手にも適用できますので、何とか区別する必要があります。)

おそらく適切なプログラミング言語を使用する方が良い考えです。

バラより配列/関連配列存在するバッシュガイド連想配列に関する追加情報。

答え3

ksh93複合変数を使用してこれを実行できます。

ksh93$ typeset -A teams
ksh93$ teams[A]=(scored=(home=3 away=7) conceded=(home=1 away=0))
ksh93$ teams[B]=(scored=(home=2 away=0) conceded=(home=3 away=1))

ksh93$ echo ${teams[A].conceded}
( away=0 home=1 )
ksh93$ echo ${teams[A].conceded.away}
0
ksh93$ teams[A].conceded.away=1

残念ながら、ハッシュのように最初から自動的に有効になるわけではありませんperl

ksh93$ foo.bar.baz=quux
ksh93: foo.bar.baz=quux: no parent

ksh93$ foo=()  # or typeset -C foo
ksh93$ foo.bar.baz=quux

ksh93$ typeset -p foo
typeset -C foo=(bar=(baz=quux))

関連情報