1

Can anyone tell me why this array creation: cccr[$string_1]=$string_2 #doesn't work?

#!/bin/bash

firstline='[Event "Marchand Open"][Site "Rochester NY"][Date "2005.03.19"][Round "1"][White "Smith, Igor"][Black "Jones, Matt"][Result "1-0"][ECO "C01"][WhiteElo "2409"][BlackElo "1911"]'

unset cccr
declare -A cccr

(IFS='['; for word in $firstline; do

string_1=$(echo $word | cut -f1 -d'"' | tr -d ' ')
string_2=$( echo $word | cut -f2 -d'"' )

if [ ! -z $string_1 ]; then # If $string_1 is not empty
cccr[$string_1]=$string_2 # why doesn't this line work?
fi

done)

echo  ${cccr[Event]} # echos null string

1 Answer 1

2

It happens because the value of string_1 is empty at the first iteration.

Example :

#!/bin/bash

firstline='[Event "Marchand Open"][Site "Rochester NY"][Date "2005.03.19"][Round "1"][White "Smith, Igor"][Black "Jones, Matt"][Result "1-0"][ECO "C01"][WhiteElo "2409"][BlackElo "1911"]'

unset cccr
declare -A cccr

(IFS='['; for word in $firstline; do

string_1=$( echo $word | cut -f1 -d'"' )
string_2=$( echo $word | cut -f2 -d'"' )

echo "$string_1 - $string_2"
#cccr[$string_1]=$string_2

done)

Output :

 - # Problem !
Event  - Marchand Open
Site  - Rochester NY
...

You have to modify your script to prevent the value of being empty.

A very simple workaround is to check the value of string_1 before using it.

Example :

# ...
string_1=$( echo $word | cut -f1 -d'"' )
string_2=$( echo $word | cut -f2 -d'"' )

if [ ! -z $string_1 ]; then # If $string_1 is not empty
    echo "$string_1 - $string_2"
    cccr[$string_1]=$string_2
fi
# ...

From the man page of [

-z STRING
              the length of STRING is zero

Output :

Event  - Marchand Open
Site  - Rochester NY
# ... No problem

EDIT

BTW, if look at the value of string_1, you will see that the value is Event' ' and not Event (there's a whitespace at the end of Event) So cccr[Event] does not exist, but cccr[Event ] exists. To fix that, you can delete the whitespaces in string_1 :

string_1=$(echo $word | cut -f1 -d'"' | tr -d ' ') # tr -d ' ' deletes all the whitespaces

EDIT 2

I forgot to tell you that it's normal if it does not work. Indeed, the loop is executed in a subshell environment. So the array is filled in the subshell, but not in the current shell. From the man page of bash :

(list) list  is  executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below).  Variable
              assignments and builtin commands that affect the shell's environment  do  not  remain  in  effect
              after the command completes.  The return status is the exit status of list.

So there are 2 solutions :

1. Don't run the loop in a subshell (remove the parentheses).

# ...
OLDIFS=$IFS
IFS='['
for word in $firstline; do
    string_1=$(echo $word | cut -f1 -d'"' | tr -d ' ')
    string_2=$(echo $word | cut -f2 -d'"')
    if [ ! -z $string_1 ]; then
        cccr[$string_1]=$string_2
    fi
done
IFS=$OLDIFS

echo "Event = ${cccr[Event]}"
echo "Site = ${cccr[Site]}"

Output :

Event = Marchand Open
Site = Rochester NY

2. Use your array in the subshell.

# ...
(IFS='['
for word in $firstline; do
    string_1=$(echo $word | cut -f1 -d'"' | tr -d ' ')
    string_2=$(echo $word | cut -f2 -d'"')
    if [ ! -z $string_1 ]; then # If $string_1 is not empty
    cccr[$string_1]=$string_2
    fi
done
echo "Event = ${cccr[Event]}"
echo "Site = ${cccr[Site]}"
)

Output :

Event = Marchand Open
Site = Rochester NY
Sign up to request clarification or add additional context in comments.

2 Comments

Yes, but I need to populate the array and process the associative array elements after the loop: echo ${cccr[Event]} (It doesn't appear that the array "cccr" actually gets populated.) Can you suggest anything?
Yes it's normal. I added an explanation in my answer.

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.