Lorccan
Lorccan

Reputation: 823

Two-Way Hash in Bash?

I call a binary [used to set the state of an external device over IP] from a bash script with arguments that are not (easily) human readable (meaningful). e.g. "video2,cbl,sat"

Consequently, I call the bash script with a more user-friendly argument, e.g. "amazon", and use an associative array to get the unfriendly argument:

declare -A state=( [amazon]="video2,cbl,sat" )
input_arg=${state[amazon]}
/usr/bin/set_state source:"$input_arg"

This is fine when I set state, but I also need to get state and return this to the [human] user, so I have the reverse hash:

declare -A current_state=( [video2,cbl,sat]="amazon" )
output=$(/usr/bin_get_state)
friendly_output=${current_state["$output"]}
echo "$friendly_output"

Is there a way to have a two-way hash in bash without maintaining two such arrays?

The same array could be used to store maps in both directions. It would work, but it doesn't feel quite right!

Upvotes: 0

Views: 234

Answers (1)

choroba
choroba

Reputation: 242333

Bash doesn't provide any means to invert a hash, so you need to iterate it yourself key by key.

#!/bin/bash
declare -A state
state=([amazon]="video2,cbl,sat"
       [netflix]="video3,cbl,inet")

declare -A current_state
for key in "${!state[@]}" ; do
    current_state["${state[$key]}"]=$key
done

You might need to verify the values are unique:

for key in "${!state[@]}" ; do
    if [[ ${current_state["${state[$key]}"]} ]] ; then  # Fix your syntax HL, SO! "
        echo Duplicate "$key". >&2
        exit 1
    fi
    ...

Upvotes: 1

Related Questions