associative array hack for bash
From: Harald (pifpafpuf_at_gmx.de)
Date: 11/02/05
- Next message: Dextro: "spliting files with specific patten occuring multiple times into three files"
- Previous message: laura fairhead: "Re: Script to change file name"
- Next in thread: William Park: "Re: associative array hack for bash"
- Reply: William Park: "Re: associative array hack for bash"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 02 Nov 2005 21:23:17 GMT
Below I dare to publish code intended to implement associative arrays
or a storage for key/value pairs. It seems to work for my limited
use. I run this with bash2 and bash3. Note that I try to allow any
special charater for the key as well as the value.
Comments welcome:
a) make it POSIX compliant,
b) improve coding (style),
c) be more efficient (no idea if this is slow),
d) break it, e.g. by storing special characters.
Never mind the yruba_ prefix. I use it in a yruba (see
http://pifpafpuf.de/yruba/userguide.xhtml)
Thanks,
Harald Kirsch
#
# A set of functions to simulate an associative array. The associative
# array is stored as a string in any variable. Both, key and value are
# encoded not to contain single vertical bars. Instead vertical bars
# are encoded as "|." A key/value pair is encoded like "||key|=value"
# and in addition, the whole string is terminated by "||".
#
#####
# usage: yruba_remove mapname key
# removes from the map given by mapname the entry for key, if any
function yruba_remove() {
local table=${!1}
local key=$(yruba_encode "$2")
local head=${table%||$key|=*}
if [ "$head" = "$table" ]; then return; fi
local tail="${table#*||$key|=*||}"
eval "$1"='"${head}||${tail}"'
}
#####
# usage: yruba_get mapname key [default]
function yruba_get() {
# usage: yruba_get mapname
local table=${!1}
local key=$(yruba_encode "$2")
local dflt=$3
local tail="${table#*||$key|=}"
if [ "$table" = "$tail" ]; then echo "$dflt"; return; fi
local value=$(yruba_decode "${tail%%||*}")
echo "$value"
}
#####
# usage: yruba_put mapname key value
# enters the key/value pair into the map with the name mapname
function yruba_put() {
if [ -z "${!1}" ]; then eval "$1"='"||"'; fi
local key=$(yruba_encode "$2")
local value=$(yruba_encode "$3")
yruba_remove "$1" "$2"
local table="${!1}"
eval "$1"='"||$key|=${value}$table"'
}
#####
# usage: mapname aryname
# Enters all keys found in the map with name mapnam into the array
# given by aryname.
# Example: yruba_keys map keys; for x in "${keys[@]}"; do...done;
function yruba_keys() {
local table=${!1}
local aname=$2
local l
while [ "$table" != "||" ]; do
local key=$(yruba_decode "${table%%|=*}")
eval l=\${\#${aname}[@]}
eval ${aname}[$l]='${key#||}'
table="||${table#||*||}"
done
}
function yruba_encode() {
local p=${1//|/|.}
echo "$p"
}
function yruba_decode() {
local p=${1//|./|}
echo "$p"
}
########################################################################
# Unsorted examples and test cases.
yruba_put ary bsq "\\'"
yruba_put ary quote \'
yruba_put ary dquote '"'
yruba_put ary '"' aaaa
yruba_put ary \' bbb
yruba_put ary "a
a" bbb
yruba_put ary "X X" "y y"
yruba_put ary " ' ' ' " ' " " " '
yruba_put ary ' " " " ' " ' ' ' "
echo $ary
yruba_keys ary keys
for x in "${keys[@]}"; do
y=$(yruba_get ary "$x")
echo ">>$x<<" ">>$y<<"
yruba_remove ary "$x"
done
echo ">>$ary<<"
-- ---------------------+--------------------------------------------- Harald Kirsch (@home)| Java Text Crunching: http://www.ebi.ac.uk/Rebholz-srv/whatizit/software
- Next message: Dextro: "spliting files with specific patten occuring multiple times into three files"
- Previous message: laura fairhead: "Re: Script to change file name"
- Next in thread: William Park: "Re: associative array hack for bash"
- Reply: William Park: "Re: associative array hack for bash"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]