Question

How do I get an associative array from a query string in Bash? - Attempt:

#!/usr/bin/env bash

# Querystring (implementation stolen from http://stackoverflow.com/q/3919755)

function populate_querystring_array ()
{
    param="$1"
    query_dict="$2"
    #for i in "${array[@]}"; do IFS="=" ; set -- $i; query_dict[$1]=$2; done

    for ((i=0; i<${#param[@]}; i+=2))
    do
        query_dict[${param[i]}]=${param[i+1]}
    done
}

q0='email=foo@bar.com&password=dfsa54'
declare -A querydict
populate_querystring_array "$q0" "$querydict"
printf "$querydict[email]"
Was it helpful?

Solution

Below should work:

#!/bin/bash

function qrystring() {
    qry=$1

    while read key value; do
        arr+=(["$key"]="$value")
    done < <(awk -F'&' '{for(i=1;i<=NF;i++) {print $i}}' <<< $qry | awk -F'=' '{print $1" "$2}')
}

q='email=foo@bar.com&password=dfsa54'
declare -A arr

qrystring "$q"

for k in ${!arr[@]}; do
    echo "$k -> ${arr[$k]}"
done

Explanation:

Im using a combination of awk commands to split the string into individual records first, then split on the = sign for kv pair.

I'm using process substitution here otherwise i would be populating a copy of the array.

EDIT:

Using a global variable to house array.

OTHER TIPS

#!/usr/bin/env bash
q0='email=foo@bar.com&password=dfsa54'
declare -A querydict
while IFS== read key value
do
    querydict["$key"]="$value"
done < <(echo "$q0" | sed 's/&/\n/g' )
printf "${querydict[email]}\n"

In the above, 's/&/\n/g' is a sed command that replaces every occurrence of & with a new line. We apply this to q0 so that every parameter assignment is on a separate line. The parameter assignments are then read into the while loop. To read each assignment, IFS== read key value is used. IFS== tells read to treat the equal sign as a word separator. Thus, each assignment is broken into two words: the first is the key and the second is the value. These are then assigned to the associative array querydict with the statement querydict["$key"]="$value".

Putting it in a function

bash differs from most modern programming languages in that its facilities for passing complex data into and out of functions are extremely limited. In the method shown below, the associative array, querydict, is a global variable:

#!/usr/bin/env bash
declare -A querydict
populate_querystring_array () {
    query="$1"
    while IFS== read arg value
    do 
        querydict["$arg"]="$value"
    done < <(echo "$query" | sed 's/&/\n/g' )
}

q0='email=foo@bar.com&password=dfsa54'
populate_querystring_array "$q0"
printf "${querydict[email]}\n"

Taking @John1024's answer I use it in a function which returns the associative array by value, simply printing out the contents using array syntax:

function parseQuery {
    local querystring="$*"
    echo -n "("
    echo "${querystring}" | sed 's/&/\n/g' | while IFS== read arg value
    do
        echo -n "[${arg}]='${value}' "
    done
    echo ")"
}

declare -A querydict=$(parseQuery "${QUERY_STRING}" )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top