14

I am able to read file into a regular array with a single statement:

local -a ary
readarray -t ary < $fileName

Not happening is reading a file into assoc. array.

I have control over file creation and so would like to do as simply as possible w/o loops if possible at all.

So file content can be following to be read in as:

keyname=valueInfo

But I am willing to replace = with another string if cuts down on code, especially in a single line code as above.

And ...

So would it be possible to read such a file into an assoc array using something like an until or from - i.e. read into an assoc array until it hits a word, or would I have to do this as part of loop?

This will allow me to keep a lot of similar values in same file, but read into separate arrays.

I looked at mapfile as well, but does same as readarray.

Finally ...

I am creating an options list - to select from - as below:

local -a arr=("${!1}")
select option in ${arr[*]}; do
    echo ${option}
    break
done

Works fine - however the list shown is not sorted. I would like to have it sorted if possible at all.

Hope it is ok to put all 3 questions into 1 as the questions are similar - all on arrays.

Thank you.

oguz ismail
  • 1
  • 16
  • 47
  • 69
mono-dr
  • 217
  • 1
  • 2
  • 9
  • I'll ask this because I always do: are you sure you want to use bash for this? I find for any real logic, it's often worth it to delegate to ruby, python, or another richer scripting language. – Jordan Samuels Aug 11 '14 at 20:00
  • @JordanSamuels So far I see that most of it can be essentially done in Bash. – konsolebox Aug 11 '14 at 20:07

1 Answers1

34

First thing, associative arrays are declared with -A not -a:

local -A ary

And if you want to declare a variable on global scope, use declare outside of a function:

declare -A ary

Or use -g if BASH_VERSION >= 4.2.

If your lines do have keyname=valueInfo, with readarray, you can process it like this:

readarray -t lines < "$fileName"

for line in "${lines[@]}"; do
   key=${line%%=*}
   value=${line#*=}
   ary[$key]=$value  ## Or simply ary[${line%%=*}]=${line#*=}
done

Using a while read loop can also be an option:

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

Or

while IFS== read -r key value; do
    ary[$key]=$value
done < "$fileName"
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • 2
    konsolebox - Just wanted to say thanks! All the code worked out really well. Finally finished implementing! – mono-dr Aug 17 '14 at 18:16
  • I think `${line...` should be quoted like `"${line..."`. Similarly `$key` should be `"$key"` and `$value` s/b `"$value"`. Still upvoted and I'll try this code in current project. Thanks. – WinEunuuchs2Unix Jun 16 '19 at 22:31
  • @WinEunuuchs2Unix It's not necessary in those instances because filename expansion and .word splitting don't happen. – konsolebox Jun 19 '19 at 19:17
  • Yes. I actually ditched the technique for this project because bash put `\` in front of every space. I went with normal array for data fields and associative array with key and value as index number to data array. – WinEunuuchs2Unix Jun 19 '19 at 19:40