thoni56 thoni56 - 1 year ago 71
Bash Question

Datadriven shell programming? Suggestions, please

I'd like to convert my shell script to use a datadriven approach. But since there are no "tables" type values in any shell (that I know of), what are suggested alternative ways to do this?

What I'm looking for is solutions that would allow one to do things like:

animals = [['horse', 300 'brown'],
['cat', 3, 'black'],
['elephant', 3000, 'grey'],
['mouse', 0.3, 'grey']]
for a in animals ; do
echo "A typical $a[1] is $a[3] and weighs about $a[2] kilograms."

More precisely, I'd like to try a number of commands and see if one of them is available, and then send arguments to it:

commands = [['c1', '-m', '-i'],
['c2', '-message', '-icon'],
['c3', '/m', '/i']]
for c in commands ; do
if exists c[1] ; then
command = c[1]
message_option = c[2]
icon_option = c[3]
$command $message_option "message" $icon_option icon

Answer Source

You can define and use associative-arrays in bash for your requirement.


# declaring the Associative array
declare -a animals


for animal in "${animals[@]}"
    myArray=(${animal//:/ })
    printf "A typical "${myArray[0]}" is "${myArray[2]}" and weighs about "${myArray[1]}" kilograms.\n"

The only tricky part in the above is parameter-expansion of type

          The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. 
If pattern begins with ‘/’, all matches of pattern are replaced with string. Normally only the first match is replaced. 

So ideally the string 'horse':300:'brown' is split as individual elements and stored in the array myArray which is later used to access individual elements in a C-style loop.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download