Reading key-value pair in Bash where value contains delimiter

Viewed 289

How to read a key-value pair file into an associative array when the value portion may have the delimiter in the value? So, split the line on the first occurrence of the delimiter, and store in an associative array.

Example KVP file contents:

key=value
key1=[SHA:]$value()%_&+=

I'd like to do something like

KVP_FILE="./file.properties"
declare -A keyvals
while read line; do 
 ??
 keyvals[$key]="$value"
done < $KVP_FILE

This is a broken code sample which loses the trailing = in the key1 from the file sample above.

while IFS=$'=' read key value; do
     [[ $key = [#!]* ]] || [[ $key = "" ]] && continue;
     keyvals[$key]=$(echo "$value" | sed 's/[\/&]/\\&/g')
   done < $SFILE
2 Answers

You could use parameter expansion to remove everything starting with the first = for the key, and everything up to the first = for the value:

declare -A keyvals

while IFS= read -r line; do
    keyvals["${line%%=*}"]=${line#*=}
done < "$KVP_FILE"

Use sed to replace first separator to a newline. Then read two lines at a time.

KVP_FILE="./file.properties"
declare -A keyvals
while read -r key && read -r value; do 
   keyvals[$key]="$value"
done < <(sed 's/=/\n/' "$KVP_FILE")
Related