Er det mulig å lage flerdimensjonale matriser i bash scripting?
Dette er mine 3 matriser :
arrayCITY=( NewYork LasVegas Detroit ) arraySTREET=( RoadStreet TreeStreet HighStreet ) arrayNUMBER=( 20 455 300 )
Nå vil jeg plassere disse 3 gruppene i bare en matrise – er dette mulig? Så vil jeg vise dem i en txt-fil. Nå gjør jeg det slik:
for ((i=0; i<${#arrayCITY[*]}; i++));do echo "${arrayCITY[i]} ${arraySTREET[i]} ${arrayNUMBER[i]}" >> TEXT.txt done
Svar
Fra 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.
Nøkkelfrase:
Bash gir endimensjonale indekserte og assosiative arrayvariabler.
Så nei, bash støtter ikke flerdimensjonale matriser.
Svar
Jeg løp inn i dette akkurat nå. Det er en ganske enkel løsning som fungerte for meg. Jeg ønsket å bruke en matrise som inneholdt et enhetsnavn og en skjermposisjon for å vise et nøkkelkart for enheten. Jeg gjorde følgende: Jeg sammenkjedet enhetsnavnet og den tilhørende skjermposisjonen i en enkelt streng ved hjelp av en avgrenser (i mitt tilfelle brukte jeg .
) som jeg visste ikke ville vises i noen av verdiene mine. Så brukte jeg cut
for å dele de sammensatte verdiene i komponentene når det var nødvendig. Det kan være en renere og enklere måte å gjøre dette på, men dette er bare for å vise at du kan lage et flerdimensjonalt utvalg, på en måte, i bash, selv om det ikke støtter det:
#!/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
Dette ligner noe på Coop.Computers svar .
Svar
Her «er en løsning som fungerer for meg. Hvis vi først setter opp matrisen slik:
arrayCSR=( Placeholder_for_0_spot NewYork RoadStreet 20 LasVegas TreeStreet 455 Detroit HighStreet 300 )
Plassholderen er der for å unngå å måtte håndtere en 0-indeks.
Deretter er hver " rad " alt som kan være delt på 3, og hver " kolonne " er 1 eller 2 mindre enn " rad " nummer.
${arrayCSR[${3}]} is 20 ${arrayCSR[${2}]} is RoadStreet ${arrayCSR[${1}]} is NewYork
Et eksempelskript er under:
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
Så enhver indeks som kan dele med 3 indikerer en " rad ", og også den tredje " kolonne " i raden. For å få den andre og første " kolonne ", trekker du 1 eller 2 deretter.
Dette kan også skaleres opp om nødvendig.
Oppdatering: Nedenfor er koden jeg bruker for å laste inn og rekke strengutskiftninger for filnavn. Den første matrisen lastes fra en fil, og deles deretter i to separate matriser.
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
Kommentarer
- At ' er en fin måte å forfalske et 2D-array hvis lengden på alle elementene er kjent (og konsistent), men vil selvfølgelig ikke fungere for elementer med variabel lengde.
- For meg vil den enkle måten være å bare bruke 3 matriser, med indeksen som den felles koblingen mellom dem.
Svar
Så mye som jeg liker Bash, er det fornuftig å bytte til andre språk. Dette er ganske greit å bruke en ordbok i 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"]))
Å kjøre dette gir:
./cities.py New York: Roadstreet 20 Las Vegas: TreeStreet 455