ループ内の中かっこ拡張を使用した配列の作成

ループ内の中かっこ拡張を使用した配列の作成

年ごとに異なる配列を作成したいと思います。ループ内で中かっこ拡張と変数を使用して配列を作成します。

私は成功せずに次のコードを試しました。

LIST={JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}
do
  declare -a 'y$year=('"$LIST"'-$year)'
  echo "${y$year[@]}"
done

結果は次の項目のリストでなければなりません。

y1998: JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
y1999: JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
...
y2011: JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011

印刷する必要はなく、ループで使用してパラメータに渡すだけです。 2番目のため、evalインループでは十分ではありません。

答え1

中かっこ拡張を延期するのは実際には次の例です。eval、特に文字列化が必要な場合 -一般的なパラメータ拡張は正しい操作を実行しません。タイムリーに。

これにより、目的のタスクが実行されます。

LIST={JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}
do
  eval "y$year=($LIST-$year)"
  tmp="y$year[@]"
  echo "${!tmp}"
done

eval配列に間接的にアクセスできないため、印刷するには配列内を文字列化する必要があります。それ以外の場合は、それ以降のすべてを取り出すことができます; tmpに使用されます間接拡張:その値に置き換えられるに設定されている場合、この反復は与えられた配列の内容に展開されますtmp(などは何に拡張されます)。"y$year[@]"$year${!tmp}${y1998[@]}

上記は次のように出力されます。

JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000
JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009
JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010
JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011

そして配列を生成しますy1998....y2011これらのdeclaresは必ずしも必要ではありませんが、eval文字列化を必要とせず、必要に応じてスキップできます。

私の考えでは、おそらくあなたが本当に望む基本的な目標を達成する方法ではないでしょう。ネストされたループは悪くありません。ループ内のどのポイントでもハードコードされている場合は抽象化できます。

答え2

これは一つの方法です(サポート拡張を含む):

unset y _y
for y in {JF,JFE,RFS,JBF,JFI,JMCB,}-{{1998..2000},{2009..2011}}
do  case "${_y=y${y#*-}[@]}"               in 
    (y${y#-}*) echo "${!_y}"               ;; 
    (*)        declare -a "${_y%???}+=($y)";; 
esac; unset y _y; done

これにより、ループのパラメータセットがfor必要なすべての値に拡張されます。追加する最後のグループには年だけが含まれます。この仕事をするすべての人のためにいいえ数字で始まるすべての項目declareに配列メンバーを追加し、y${y##*[!0-9]}各番号についてするecho印刷してください。

したがって、最初の36回の反復では各配列を作成し、次の6回の反復では各配列を印刷します。出力は次のとおりです

JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000
JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009
JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010
JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011

ここに代替案があります。おそらく...

for year in 1998 1999 2000 2009 2010 2011
do  printf "%s-$year " JF JFE RFS JBF JFI JMCB
echo; done

これは少なくとも同じ出力を提供します。また、配列に保存すれば可能です。

for year in 1998 1999 2000 2009 2010 2011
do  declare -a "y$year=($(printf "%s-$year " JF JFE RFS JBF JFI JMCB |
               tee /dev/fd/2 ))"
    year=y$year[@]; year=(${!year})
    echo "${#year[@]}"
done 2>&1; unset year

これは2番目のコマンドの出力ですが、1番目のコマンドは6と同じ内容を出力します。これは単に配列メンバー数を表します。

JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998 6
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999 6
JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000 6
JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009 6
JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010 6
JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011 6

覚えておいてください。これはdeclareコマンドであり、var$expand=(something $expand)引数は単に引数です。declareのパラメータは、他のパラメータと同じ方法で拡張されます。これはvar$expand=$expand文の場合には該当しません。したがって、declare間接的に行うのと同じ方法で間接的に行うことができますexport。私の考えでは、あなたが使った難しい引用は不要だと思います。

答え3

中かっこ拡張を介して配列に変換しますset --

その後、出力を構成する単純な2Dループがあります。

set -- {JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}; do
    printf "y%s: " $year
    for code do
        printf "%s-%s " $code $year
    done
    echo
done

生産する:

y1998: JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
y1999: JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
y2000: JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000
y2009: JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009
y2010: JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010
y2011: JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011

関連情報