3

I'm trying to read a structured file into an associative array in Bash. The file stores in each line a person name and a person address. For example:

person1|address1
person2|address2
...
personN|addressN

I am using the script below.

#!/bin/bash
declare -A address
while read line
do
    name=`echo $line | cut -d '|' -f 1`
    add=`echo $line | cut -d '|' -f 2`
    address[$name]=$add
    echo "$name - ${address[$name]}"
done < adresses.txt

for name in ${!address[*]}
do
    echo "$name - ${address[$name]}"
done

The script work properly. However, in the FOR loop, i'm having some problems when the person name has spaces (For example "John Nobody"). How can I fix this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Zaratruta
  • 2,097
  • 2
  • 20
  • 26

1 Answers1

6

You need to use more quotes to maintain the values with whitespace as "words":

declare -A array
while IFS='|' read -r name value; do 
    array["$name"]="$value"
done <<END
foo bar|baz
jane doe|qux
END

for key in "${!array[@]}"; do echo "$key -> ${array[$key]}"; done
# .........^............^ these quotes fix your error.
foo bar -> baz
jane doe -> qux

The quotes in "${!array[@]}" in the for loop mean that the loop iterates over the actual elements of the array. Failure to use the quotes means the loop iterates over all the individual whitespace-separated words in the value of the array keys.

Without the quotes you get:

for key in ${!array[@]}; do echo "$key -> ${array[$key]}"; done
foo -> 
bar -> 
jane -> 
doe -> 
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 1
    Note you have to use `[@]` not `[*]` -- I've illustrated the difference previously: http://stackoverflow.com/a/12316565/7552 – glenn jackman Nov 02 '16 at 21:19