kombinování 3 samostatných polí do jednoho vícerozměrného pole v bash

Je možné vytvořit vícerozměrná pole v bash skriptování?

Toto jsou moje 3 pole :

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

Nyní chci dát tato 3 pole do jediného pole – je to možné? Pak je chci ukázat v souboru txt. Teď to dělám takto:

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

Odpověď

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

Klíčová fráze:

Bash poskytuje jednorozměrné indexované a asociativní proměnné pole.

Takže ne, bash nepodporuje vícerozměrná pole.

Odpověď

Právě jsem do toho narazil. Pro mě fungovalo celkem jednoduché řešení. Chtěl jsem použít pole, které obsahovalo název zařízení a polohu obrazovky, pro zobrazení mapy klíčů pro zařízení. Udělal jsem následující: Zřetězil jsem název zařízení a přidruženou pozici obrazovky do jednoho řetězce pomocí oddělovače (v mém případě jsem použil . ), o kterém jsem věděl, že se neobjeví v žádné z mých hodnot. Potom jsem pomocí cut v případě potřeby rozložil složené hodnoty na jejich součásti. Může existovat čistší a jednodušší způsob, jak to udělat, ale to jen ukazuje, že můžete vytvořit vícerozměrné pole svým způsobem v bash, i když to nepodporuje:

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

Je to něco podobného jako odpověď Coop.Computer .

Odpověď

Toto je řešení, které pro mě funguje. Pokud pole nastavíme poprvé takto:

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

Je tam zástupný symbol aby se nemusel zabývat indexem 0.

Potom každý " řádek " je cokoli, co lze děleno 3 a každý " sloupec " je o 1 nebo 2 menší než " řádek " číslo.

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

Níže je ukázkový skript:

  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  

Takže jakýkoli index, který lze rozdělit na 3, označuje " řádek " a také třetí " sloupec " v řádku. Chcete-li získat druhý a první " sloupec ", odečtěte odpovídajícím způsobem 1 nebo 2.

Tím se také může zvětšit v případě potřeby.

Aktualizace: Níže je uveden kód, který používám k načtení a nahrazení řetězců pro názvy souborů. První pole je načteno ze souboru a poté je rozděleno do 2 samostatných polí.

  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  

Komentáře

  • Tento ' je úhledný způsob, jak předstírat 2D pole, pokud jsou známy délky všech prvků (a konzistentní), ale samozřejmě nebude fungovat pro prvky s proměnnou délkou.
  • Pro mě by jednoduchým způsobem bylo pouhé použití 3 polí, přičemž index je společným odkazem mezi nimi.

Odpověď

Bash se mi sice líbí, ale má smysl občas přepnout na jiné jazyky. Toto je poměrně jednoduché pomocí slovníku v Pythonu:

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

Spuštění tohoto výnosu:

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

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *