0

Noble StackOverflow readers,

I have a comma seperated file, each line of which I am putting into an array. Data looks as so...

25455410,GROU,AJAXa,GROU1435804437
25455410,AING,EXS3d,AING4746464646
25455413,TRAD,DLGl,TRAD7176202067

There are 103 lines and I am able to generate the 103 arrays without issue.

n=1; while read -r OrdLine; do
    IFS=',' read -a OrdLineArr${n} <<< "$OrdLine"
    let n++
done < $WkOrdsFile

HOWEVER, I can only access the arrays as so...

echo "${OrdLineArr3[0]}  <---Gives 25455413

I cannot access it with the number 1-103 as a variable - for example the following doesn't work...

i=3
echo "${OrdLineArr${i}[0]}

That results in...

./script2.sh: line 24: ${OrdLineArr${i}[0]}: bad substitution

I think that the answer might involve 'eval' but I cannot seem to find a fitting example to borrow. If somebody can fix this then the above code makes for a very easy to handle 2d array replacement in bash!

Thanks so much for you help in advance!

Dan

3
  • 1
    Possibly duplicate of stackoverflow.com/questions/6724056/…. Commented Nov 17, 2013 at 1:22
  • Bash supports only one-dimensional arrays and you would be better off using Perl for this task. If you really have to use Bash check out tldp.org/LDP/abs/html/arrays.html specifically example 27.17 Commented Nov 17, 2013 at 1:28
  • @ruakh - the indirect expansion within a function worked a treat. Is a very nice paradigm for 2-d arrays when forced to use bash to process them! Thanks so much! Commented Nov 20, 2013 at 11:30

3 Answers 3

1

You can use indirect expansion. For example, if $key is OrdLineArr4[7], then ${!key} (with an exclamation point) means ${OrdLineArr4[7]}. (See §3.5.3 "Shell Parameter Expansion" in the Bash Reference Manual, though admittedly that passage doesn't really explain how indirect expansion interacts with arrays.)

I'd recommend wrapping this in a function:

function OrdLineArr () {
    local -i i="$1"          # line number (1-103)
    local -i j="$2"          # field number (0-3)
    local key="OrdLineArr$i[$j]"
    echo "${!key}"
}

Then you can write:

echo "$(OrdLineArr 3 0)"        # prints 25455413
i=3
echo "$(OrdLineArr $i 0)"       # prints 25455413

This obviously isn't a total replacement for two-dimensional arrays, but it will accomplish what you need. Without using eval.

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

5 Comments

This is definitely the best answer, yet, the echo statement at the end of the function OrdLineArr will remove trailing newlines if any. If this is a concern, use a global variable for the return value of that function, e.g., OrdLineArr_ret=${!key}.
Another quick comment, you can have access to the full array with aryp=OrdLineArr[@]: then "${!aryp}" will expand to the full array.
@gniourf_gniourf: Re: trailing newlines: Yeah, I thought about that (it's one of the reasons I don't consider this a total replacement for two-dimensional arrays), but the OP's array obviously will never have newlines in its elements, so I considered it O.K.
@gniourf_gniourf: By the way, it's actually not the echo that removes the trailing newlines, but rather the command-substitution that I wrapped OrdLineArr in when I called it. If ${OrdLineArr3[0]} ends in a sequence of newlines, then OrdLineArr 3 0 will properly print those newlines, but echo "$(OrdLineArr 3 0)" will discard them. (That's a bit pedantic, but it means that a sufficiently motivated caller could work around it by writing something like foo="$(OrdLineArr 3 1 ; echo .)" ; foo="${foo%.}".)
If the goal is to put it in a variable then the motivated caller will discard this function altogether and instead create one that takes a variable name as an extra parameter and will return the value in this variable with printf -v.
0

eval is usually a bad idea, but you can do it with:

eval echo "\${OrdLineArr$i[0]}"

Comments

0

I would store each line in an array, but split it on demand:

readarray OrdLineArr < $WkOrdsFile
...
OrdLine=${OrdLineArr[i]}
IFS=, read -a Ord <<< "$OrdLine"

However, bash isn't really equipped for data processing; it's designed to facilitate process and file management. You should consider using a different language.

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.