ramesh.metta
ramesh.metta

Reputation: 139

split a line separated by space into an associative array

if i have a variable with data as below:

Audit 9201 Management 9202 Inventory 9203 Source 9204 Flemingo 9205

i'm trying to convert my $var into an expected associative array as below.

var="Audit 9201 Management 9202 Inventory 9203 Source 9204 Flemingo 9205"
declare -A varMap
$ varMap[Audit]=9201
$ varMap[Management]=9202
$ varMap[Inventory]=9203
$ varMap[Source]=9204
$ varMap[Flemingo]=9205

is there any efficient way to turn above variable $var into an associative array so that i can perform lookup based on key in my remaining piece of code ?

Upvotes: 0

Views: 575

Answers (4)

Gilles Quénot
Gilles Quénot

Reputation: 184965

Like this, simple, readable and efficient :)

# declare a simple string
var='Audit 9201 Management 9202 Inventory 9203 Source 9204 Flemingo 9205'

# declare a simple array, using word spliting
arr=( $var )

# declare an associative array
declare -A varmap

# iterating over array to feed varmap associative array
for ((i=0; i<${#arr[@]}; i+=2)) {
    varmap[${arr[i]}]=${arr[i+1]}
}  

# new request from comments: the max value with key ending with `Management` :
for i in ${!varmap[@]}; do
    if [[ $i == *Management ]]; then
        if ((varmap[$i] > max)); then
            max=${varmap[$i]}
            var=$i
        fi
    fi
done

# test of one of a key
echo ${varmap[Management]}

 Output

9202

Upvotes: 2

RavinderSingh13
RavinderSingh13

Reputation: 133428

Could you please try following. This will create dynamic automated script which will have automated array creation and will print its keys and values too. (these are test samples provided by OP itself in post)

var="Audit 9201 Management 9202 Inventory 9203 Source 9204 Flemingo 9205"
echo "$var" | 
awk -v s1="\"" -v array_name="arrvar" '
BEGIN{
  print "declare -A " array_name
}
{
  for(i=1;i<=NF;i+=2){
    print array_name "["$i"]="$(i+1)
  }
}
END{
  print "echo keys, values here for array.." ORS \
  "for key in " s1 "${!"array_name"[@]}" s1 "; do echo " s1 "$key => ${"array_name"[$key]}" s1 "; done"
}
' > file.ksh;chmod 755 file.ksh;./file.ksh

Following shell script will be created by above command:

cat file.ksh
declare -A arrvar
arrvar[Audit]=9201
arrvar[Management]=9202
arrvar[Inventory]=9203
arrvar[Source]=9204
arrvar[Flemingo]=9205
echo keys, values here for array..
for key in "${!arrvar[@]}"; do echo "$key => ${arrvar[$key]}"; done

When we run script it will give following output:

keys, values here for array..
Audit => 9201
Flemingo => 9205
Management => 9202
Source => 9204
Inventory => 9203

Logical explanation:

  • Create/define a shell variable (in this case it is var).
  • We can provide array named (vararr in this example).
  • This will create a script named file.ksh which you can change it as per your wish.
  • What awk code is doing, it is reading var(shell variable) then its printing command to create associative array named provided by you. It is also printing keys and values of that array. NOTE: it is writing only commands to do so NOT executing them as of now.
  • Its saving output into a script file, named file.ksh(you can keep any name you need).
  • Now permissions are given to file.ksh and running it, which will actually create an array named provided by you and print its values with indexes too.

Upvotes: 2

oguz ismail
oguz ismail

Reputation: 50750

while test "$var"; do
    read -r key value var <<<"$var"
    varMap[$key]=$value
done

Upvotes: 2

tshiono
tshiono

Reputation: 22012

Would you try the following:

var="Audit 9201 Management 9202 Inventory 9203 Source 9204 Flemingo 9205"
declare -A varMap="($(sed 's/\([^[:blank:]]\+\)[[:blank:]]\+\([^[:blank:]]\+\)/\[\1]=\2/g' <<< "$var"))"

# test
for i in "${!varMap[@]}"; do
    echo "$i => ${varMap[$i]}"
done

Result:

Audit => 9201
Flemingo => 9205
Management => 9202
Source => 9204
Inventory => 9203

Upvotes: 1

Related Questions