3

I am having some trouble adding a string to an array within a loop. For some reason it always adds the same line. Here is my code:

declare -a properties
counter=0

while read line
do

    if [[ ${line} == *=* ]]
    then
        properties[${counter}]=${line}
        (( counter=counter + 1 ))
    fi
done < ${FILE}

for x in ${!properties[@]}
do
    echo "the value is $properties[x]"
done

For some reason each element in the array is the first line in the file. I must be doing something wrong, just not sure what.

Any help would be greatly appreciated

3
  • 2
    Change $properties[x] in your echo line to ${properties[$x]}... Commented Jan 14, 2014 at 20:36
  • This is a Bash script. Why do you tag ksh? Commented Jan 14, 2014 at 22:32
  • The script will work in both bash and ksh93 if the declare ... is removed. Simple arrays are created on the fly in both. Commented Jan 15, 2014 at 16:57

4 Answers 4

4

Try this script:

declare -a properties
while read line
do
   [[ "${line}" == *=* ]] && properties+=("$line")
done < "${FILE}"

for x in "${properties[@]}"
do
   echo "the value is "$x"
done
Sign up to request clarification or add additional context in comments.

2 Comments

Great improvement, but please double-quote ${properties[@]} to prevent unwanted shell expansions.
This eliminates the bug in the original script by looping x over the expanded values, instead of the index. The changes in the upper loop detract from the original bug.
1

As @twalberg mentions in this comment, the problem is not in the top loop, but in the bottom one:

for x in ${!properties[@]}
do
    echo "the value is $properties[x]"
done

Array references always need braces { ... } to expand properly.

For some reason each element in the array is the first line in the file.

Not so. The array is correctly populated, but you need to change the reference to the array from:

echo "the value is $properties[x]"

to:

echo "the value is ${properties[x]}"

Just a simple oversight.

1 Comment

+1 for explaining the problem and showing me that variable references in array subscripts need not be $-prefixed ([x] vs. [$x]) (and that subscripts can even be arithmetic expressions).
0

A much simpler way to add an element to an array is to simply use the syntax:

VARNAME+=("content")

Also, as written, your bug may be here:

(( counter=counter + 1 ))

It probably should be one of these three:

(( counter=$counter + 1 ))
counter+=1
counter=$[$counter+1]
counter=$(($counter + 1))

2 Comments

Your recommendation for building the array is helpful, but please consider removing the rest of your answer: Not only is (( counter=counter + 1 )) correct (albeit clumsy), your alternatives are not an improvement and in the case of counter+=1 incorrect. If anything, (( ++counter )) is the most concise form to use.
Correct, but does not answer the question. And then, you missed an option: [[ ${line} == *=* ]] && properties[counter++]=${line} :-)
0

This KornShell (ksh) script worked fine for me. Let me know if anything.

readFileArrayExample.ksh

#! /usr/bin/ksh

file=input.txt
typeset -i counter=0

while read line
do
    if [[ ${line} == *=* ]]; then
        properties[${counter}]="${line}"
        ((counter = counter + 1))
        echo "counter:${counter}"
    fi
done < "${file}"

#echo ${properties[*]}

for x in "${properties[@]}"
do
    echo "${x}"
done

readFileArrayExample.ksh Output:

@:/tmp #ksh readFileArrayExample.ksh
counter:1
counter:2
counter:3
a=b
a=1
b=1
@:/tmp #

input.txt

a-b
a+b
a=b
a=1
b=1
1-a

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.