2

I want to create a dictionary in bash from a text file which looks like this:

H96400275|A
H96400276|B
H96400265|C
H96400286|D

Basically I want a dictionary like this from this file file.txt:

KEYS        VALUES
H96400275 = A
H96400276 = B
H96400265 = C
H96400286 = D

I created following script:

#!/bin/bash
declare -a dictionary

while read line; do 

  key=$(echo $line | cut -d "|" -f1)
  data=$(echo $line | cut -d "|" -f2)
  dictionary[$key]="$data"
done < file.txt


echo ${dictionary[H96400275]}

However, this does not print A, rather it prints D. Can you please help ?

3
  • Closely related: stackoverflow.com/questions/38964946/… Commented Nov 19, 2019 at 7:07
  • 1
    Don't create an additional subshell for each call to cut simply use parameter expansions key="${line%|*}" and data="${line#*|}", or just dictionary[${line%|*}]=${line#*|} (after fixing the -a to -A problem) Commented Nov 19, 2019 at 7:23
  • There is more than one remark on this post! Please consider smart oguz ismail's answer Commented Nov 19, 2019 at 8:39

3 Answers 3

8

Associative arrays (dictionaries in your terms) are declared using -A, not -a. For references to indexed (ones declared with -a) arrays' elements, bash performs arithmetic expansion on the subscript ($key and H96400275 in this case); so you're basically overwriting dictionary[0] over and over, and then asking for its value; thus D is printed.

And to make this script more effective, you can use read in conjunction with a custom IFS to avoid cuts. E.g:

declare -A dict

while IFS='|' read -r key value; do
    dict[$key]=$value
done < file

echo "${dict[H96400275]}"

See Bash Reference Manual § 6.7 Arrays.

Sign up to request clarification or add additional context in comments.

1 Comment

That's another good way to avoid to subshells associated with calling cut.
5

the only problem is that you have to use -A instead of -a

      -a     Each name is an indexed array variable (see Arrays above).
      -A     Each name is an **associative** array variable (see Arrays above).

Comments

0

What you want to do is so named associative array. And to declare it you need to use command:

declare -A dictionary

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.