3つの別々の配列をbashで1つの多次元配列に結合する

bashスクリプトで多次元配列を作成することは可能ですか?

これらは私の3つの配列です:

arrayCITY=( NewYork LasVegas Detroit ) arraySTREET=( RoadStreet TreeStreet HighStreet ) arrayNUMBER=( 20 455 300 ) 

これらの3つの配列を1つの配列に入れたいのですが、これは可能ですか?次に、それらをtxtファイルで表示します。今、私はこのようにしています:

for ((i=0; i<${#arrayCITY[*]}; i++));do echo "${arrayCITY[i]} ${arraySTREET[i]} ${arrayNUMBER[i]}" >> TEXT.txt done 

回答

Arrays Bash provides one-dimensional indexed and associative array variables. Any variable may be used as an indexed array; the declare builtin will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement that members be indexed or assigned contiguously. Indexed arrays are referenced using integers (including arithmetic expressions) and are zero-based; associative arrays are referenced using arbitrary strings. Unless otherwise noted, indexed array indices must be non-negative integers. 

キーフレーズ:

Bashは1次元のインデックス付き連想配列変数を提供します。

つまり、bashは多次元配列をサポートしていません。

回答

たった今これに遭遇しました。私のために働いたかなり簡単な解決策があります。デバイス名と画面位置を含む配列を使用して、デバイスのキーマップを表示したかったのです。次のことを行いました。区切り文字を使用して、デバイス名と関連する画面位置を1つの文字列に連結しました(私の場合は、 . )は、どの値にも表示されないことを知っていました。次に、cutを使用して、必要に応じて複合値をコンポーネントに分割しました。これを行うためのよりクリーンで簡単な方法があるかもしれませんが、これは、多次元配列をサポートしていなくても、ある意味でbashで作成できることを示すためのものです。

#!/bin/bash # List of devices and screen positions for key maps. DEV_LIST=( g13.+2560+30 g510s.+3160+30 g502.+2560+555 ) # This just echoes the device name and the screen position. for DEV in "${DEV_LIST[@]}"; do DEVICE=$(echo $DEV | cut -f1 -d.) SCREEN_POSITION=$(echo $DEV | cut -f2 -d.) echo "$DEVICE" echo "$SCREEN_POSITION" done exit 

これは Coop.Computerの回答にいくぶん似ています。

回答

ここに “私に役立つソリューションがあります。最初に次のように配列を設定した場合:

  arrayCSR=( Placeholder_for_0_spot NewYork RoadStreet 20 LasVegas TreeStreet 455 Detroit HighStreet 300 )  

プレースホルダーはそこにあります0インデックスを処理する必要がないようにします。

次に、各"行"は次のようになります。 3で割ると、各"列"は"より1または2少なくなります。 row "番号。

${arrayCSR[${3}]} is 20 ${arrayCSR[${2}]} is RoadStreet ${arrayCSR[${1}]} is NewYork 

サンプルスクリプトは次のとおりです。

  arrayCSR=( CsR NewYork RoadStreet 20 LasVegas TreeStreet 455 Detroit HighStreet 300 ) for p in $( seq 1 ${#arrayCSR[*]} ) do if [[ "${arrayCSR[${p}]}" == "" ]] # Don"t run if empty then true elif [[ $((p % 3 )) -eq 0 ]] # We have 3 "columns" in the array then echo " ${arrayCSR[$(( p - 2 ))]} ${arrayCSR[$(( p - 1))]} ${arrayCSR[${p}]}" fi done  

したがって、3で除算できるインデックスは、"行を示します"、および行の3番目の"列"。 2番目と1番目の"列"を取得するには、それに応じて1または2を減算します。

これもスケールアップできます必要に応じて。

更新:以下は、ファイル名の文字列置換のロードと配列に使用するコードです。最初の配列はファイルから読み込まれ、2つの別々の配列に分割されます。

  readarray -t string_replace < ~/scripts/string_replace.lst # List of things to remove from name for p in $( seq 0 ${#string_replace[*]} ); do old_name_element[${p}]="${string_replace[${p}]%%,*}" new_name_element[${p}]="${string_replace[${p}]:$((${#old_name_element[${p}]}+1))}" done string_replace=() # Clear old array  

コメント

  • その'すべての要素の長さがわかっている場合、2D配列を偽造するための優れた方法(および一貫性があります)が、もちろん可変長要素では機能しません。
  • 私にとって簡単な方法は、3つの配列を使用し、インデックスをそれらの間の共通リンクにすることです。

回答

Bashが好きなのと同じくらい、他の言語に切り替えるのは理にかなっています。 Pythonで辞書を使用すると、これはかなり簡単です。

#!/usr/bin/env python3 cities = { "New York": { "Street": "Roadstreet", "Number": 20 }, "Las Vegas": { "Street": "TreeStreet", "Number": 455 } } for city in cities: print(str(city) + ": " + str(cities[city]["Street"]) + " " + str(cities[city]["Number"])) 

これを実行すると、次のようになります。

./cities.py New York: Roadstreet 20 Las Vegas: TreeStreet 455 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です