bashで3つの別々の配列を1つの多次元配列にマージする

bashで3つの別々の配列を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

答え1

からman 1 bash

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は多次元配列をサポートしません。

答え2

私はこれにぶつかりました。私のために働いた非常に簡単な解決策があります。デバイス名と画面位置を含む配列を使用してデバイスのキーマップを表示したいです。私は次のことをしました。区切り文字を使用して、デバイス名と関連する画面位置を文字列で連結しました(私の場合は次のようにしました)。 .)私はそれが私の価値に現れないことを知っています。その後cut、必要に応じて複合値をコンポーネント部分に分解することがよくあります。これを行うよりクリーンで簡単な方法があるかもしれませんが、これはbashがサポートしていなくても、ある程度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の答え

答え3

これは私に合ったソリューションです。最初に次のように配列を設定した場合:

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

プレースホルダは、ゼロ個のインデックスを処理しないために存在します。

これにより、各「行」は3で割ることができる任意の数字であり、各「列」は「行」の数より1または2が少なくなります。

${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

答え4

私は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

関連情報