Kombinieren von 3 separaten Arrays zu einem mehrdimensionalen Array in Bash

Ist es möglich, mehrdimensionale Arrays in Bash-Skripten zu erstellen?

Dies sind meine 3 Arrays :

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

Jetzt möchte ich diese 3 Arrays in nur einem Array zusammenfassen – ist das möglich? Dann möchte ich sie in einer txt-Datei anzeigen. Jetzt mache ich es so:

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

Antwort

Von 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. 

Schlüsselphrase:

Bash bietet eindimensionale indizierte und assoziative Array-Variablen.

Nein, bash unterstützt also keine mehrdimensionalen Arrays.

Antwort

Ich bin gerade darauf gestoßen. Es gibt eine ziemlich einfache Lösung, die für mich funktioniert hat. Ich wollte ein Array verwenden, das einen Gerätenamen und eine Bildschirmposition enthält, um eine Tastenkarte für das Gerät anzuzeigen. Ich habe Folgendes getan: Ich habe den Gerätenamen und die zugehörige Bildschirmposition mithilfe eines Trennzeichens zu einer einzigen Zeichenfolge verkettet (in meinem Fall habe ich . ), von dem ich wusste, dass es in keinem meiner Werte erscheinen würde. Dann habe ich cut verwendet, um die zusammengesetzten Werte bei Bedarf in ihre Komponenten zu zerlegen. Es gibt vielleicht eine sauberere und einfachere Möglichkeit, dies zu tun, aber dies soll nur zeigen, dass Sie ein mehrdimensionales Array in gewisser Weise in Bash erstellen können, obwohl es dies nicht unterstützt:

#!/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 

Dies ähnelt in etwa der Antwort von Coop.Computer .

Antwort

Hier ist eine Lösung, die für mich funktioniert. Wenn wir das Array zuerst so einrichten:

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

Der Platzhalter ist vorhanden Um zu vermeiden, dass Sie sich mit einem 0-Index befassen müssen.

Dann ist jede " Zeile " alles, was sein kann geteilt durch 3, und jede " -Spalte " ist 1 oder 2 kleiner als die " Zeile " Nummer.

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

Ein Beispielskript befindet sich unten:

  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  

Jeder Index, der durch 3 teilen kann, zeigt also eine " Zeile " und auch die dritte " Spalte " in der Zeile. Um die zweite und erste " -Spalte " zu erhalten, subtrahieren Sie 1 oder 2 entsprechend.

Dies kann auch skaliert werden falls erforderlich.

Update: Im Folgenden finden Sie Code, den ich zum Laden und Array von Zeichenfolgenersetzungen für Dateinamen verwende. Das erste Array wird aus einer Datei geladen und dann in zwei separate Arrays aufgeteilt.

  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  

Kommentare

  • Das ' ist eine gute Möglichkeit, ein 2D-Array zu fälschen, wenn die Länge aller Elemente bekannt ist (und konsistent), funktioniert aber natürlich nicht für Elemente variabler Länge.
  • Für mich wäre der einfache Weg, nur 3 Arrays zu verwenden, wobei der Index die gemeinsame Verbindung zwischen ihnen ist.

/ ul>

Antwort

So sehr ich Bash mag, ist es sinnvoll, manchmal in andere Sprachen zu wechseln. Dies ist mit einem Wörterbuch in Python ziemlich einfach:

#!/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"])) 

Wenn Sie dies ausführen, erhalten Sie:

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.