combinando 3 array separati in un array multidimensionale in bash

È possibile creare array multidimensionali nello scripting bash?

Questi sono i miei 3 array :

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

Ora voglio mettere questi 3 array in un solo array: è possibile? Quindi voglio mostrarli in un file txt. Ora lo faccio in questo modo:

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

Rispondi

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

Frase chiave:

Bash fornisce variabili array unidimensionali indicizzate e associative.

Quindi, no, bash non supporta array multidimensionali.

Risposta

Mi sono imbattuto in questo solo ora. Cè una soluzione abbastanza semplice che ha funzionato per me. Volevo utilizzare un array che conteneva un nome del dispositivo e una posizione sullo schermo per visualizzare una mappa dei tasti per il dispositivo. Ho fatto quanto segue: ho concatenato il nome del dispositivo e la posizione dello schermo associata in una singola stringa, utilizzando un delimitatore (nel mio caso, ho utilizzato . ) che sapevo non sarebbe apparso in nessuno dei miei valori. Quindi ho utilizzato cut per suddividere i valori compositi nei loro componenti quando necessario. Potrebbe esserci un modo più pulito e più semplice per farlo, ma questo è solo per mostrare che puoi creare un array multidimensionale, in un certo senso, in bash, anche se non lo supporta:

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

Questo è in qualche modo simile alla risposta di Coop.Computer .

Risposta

Ecco “una soluzione che funziona per me. Se per prima cosa impostiamo larray in questo modo:

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

Il segnaposto è lì per evitare di dover gestire un indice 0.

Quindi, ogni " riga " è tutto ciò che può essere diviso per 3 e ogni " colonna " è 1 o 2 inferiore alla " riga " numero.

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

Di seguito è riportato uno script di esempio:

  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  

Quindi qualsiasi indice che può dividere per 3 indica una " riga " e anche la terza " colonna " nella riga. Per ottenere la seconda e la prima " colonna ", sottrai 1 o 2 di conseguenza.

Questo può anche aumentare se necessario.

Aggiornamento: di seguito è riportato il codice che utilizzo per caricare e un array di sostituzioni di stringhe per i nomi dei file. Il primo array viene caricato da un file, quindi viene suddiviso in 2 array separati.

  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  

Commenti

  • Questo ' è un bel modo per simulare un array 2D se la lunghezza di tutti gli elementi è nota (e consistente), ma ovviamente non funzionerà per elementi di lunghezza variabile.
  • Per me, il modo più semplice sarebbe usare solo 3 array, con lindice che è il collegamento comune tra di loro.

Risposta

Per quanto mi piaccia Bash, a volte ha senso passare ad altre lingue. Questo è abbastanza semplice usare un dizionario in 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"])) 

Eseguire questo produce:

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

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *