0

I searched for array and map structures on bash scripting. It seems a bit hard to locate the value of a key without looping through it. One of the topics I had a look was How to define hash tables in Bash?. It didn't help much to me though.

In simple words, I just want to be able to access any value without loops.

#!/bin/bash

ARRAY=("kevin:42"
        "jack:45"
        "tom:22")

echo printing jack value: ${ARRAY["jack"]#*:}

Output

printing jack value: 42

Expected Output

printing jack value: 45

If you know any simple ways to do so, would be awesome. Thanks for the help in advance!

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
cosmos-1905-14
  • 783
  • 2
  • 12
  • 23
  • 3
    You should be using an **associative** array instead of a numerically indexed one. – Charles Duffy Feb 25 '23 at 00:45
  • 1
    See [BashFAQ #6: "How can I use variable variables (indirect variables, pointers, references) or associative arrays?"](http://mywiki.wooledge.org/BashFAQ/006#Associative_Arrays) (and ignore the parts about "variable variables" -- they're mostly a kluge for when you're stuck with a shell that doesn't have associative arrays). – Gordon Davisson Feb 25 '23 at 00:49
  • 1
    BTW, all-caps variable names are in space used by variables meaningful to the shell itself, whereas names with at least one lowercase character are reserved for applications (like your scripts). See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html, keeping in mind that setting a shell variable overwrites any like-named environment variable. – Charles Duffy Feb 25 '23 at 00:49
  • Reading the question you linked, by the way, its answers are completely correct and on-point; I don't understand how/why they didn't help you. If you start a new question and, within it, show how you tried to apply those answers and the specific failure mode you encountered (with enough detail that others can produce that failure themselves), that would be a stronger question (in terms of being concretely differentiated from the prior instance and thus not eligible to be closed as a duplicate). – Charles Duffy Feb 25 '23 at 00:51
  • (BTW, the reason `${ARRAY["jack"]}` doesn't work the way you want is that for a numerically-indexed array, `jack` gets converted to a number by evaluating it as a variable in the same way is is done in `echo "$((jack))"`; the empty string turns into 0) – Charles Duffy Feb 25 '23 at 01:01

1 Answers1

2

You're looking for what bash calls an associative array, and what Golang (f/e) would call a map[string]string.

#!/usr/bin/env bash

declare -A array=(
 ["kevin"]=42
 ["jack"]=45
 ["tom"]=22
)

echo "printing jack value: ${array[jack]}"

Note that this is a feature that was added in bash 4.0; on systems like MacOS with bash 3.x, you'll get an error saying declare -A is invalid, and will want to install a newer interpreter.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441