0

I am trying to implement a n x n 2D matrix using shell script. I am taking input for matrix elements using two for loop. But when I print the values after getting the elements using separate loop, It only prints last row n times. Please find below code and outputs.

#!/bin/bash
read -p "Enter the size of matrix: " n
c=`expr $n - 1`

# Get the matrix elements

for i in $(seq 0 1 $c)
do
        for j in $(seq 0 1 $c)
        do
                read -p "enter the value of $i, $j element " arr[$i,$j]
        done
done

# Print the matrix

for i in $(seq 0 1 $c)
do
        for j in $(seq 0 1 $c)
        do
                echo -n "${arr[$i,$j]} "
        done
        echo
done

Output:

ubuntu@ip-172-31-6-229:~/shellscript$ ./matrix.sh
Enter the size of matrix: 3
enter the value of 0, 0 element 1
enter the value of 0, 1 element 2
enter the value of 0, 2 element 3
enter the value of 1, 0 element 4
enter the value of 1, 1 element 5
enter the value of 1, 2 element 6
enter the value of 2, 0 element 7
enter the value of 2, 1 element 8
enter the value of 2, 2 element 9
7 8 9
7 8 9
7 8 9

As you can see, While printing output, It is printing last row in all the rows. Can someone please help me with this ?

Shell: BASH

Thanks

2
  • Can't you just store the data in a list and access element (i,j) at index i+k*j, where k is the number of columns?
    – Kusalananda
    Sep 28, 2020 at 10:50
  • "I am trying to implement a n x n 2D matrix using shell script" this very much feels like you're using the wrong tool for the job
    – roaima
    Sep 28, 2020 at 12:49

2 Answers 2

2

TL;DR

Add declare -A arr before reading in the values in the loop and your code will work as you wish it to. But do read the longer version since you probably do not know what you are doing.

Longer version

Bash does not support multi-dimensional arrays. What you are essentially creating here is called an associative array and you need to explicitly declare that the variable is an associative array for it to work. Hence the declare -A arr. For more information, you can read up here.

You can actually see how your array is getting modified by printing out the array after each input so that your inner loop will look something like :

        for j in $(seq 0 1 $c)
        do
                read -p "enter the value of $i, $j element " arr[$i,$j]
                echo ${arr[*]}
        done

What we notice is that only 3 indices are created (for n=3), 0, 1 and 2 and the values at corresponding indices are replaced as the latter index j changes.

Without declare -A we're not creating an associative array, but a regular one indexed with integers. And that's where the issue lies. The index is taken as an arithmetic expression, and in arithmetic expressions, the comma operator evaluates both sides, but returns just the value of the right hand side.

2
  • 2
    Without declare -A they're not creating an associative array, but a regular one indexed with integers. And that's exactly the problem: when indexing one, the index is taken as an arithmetic expression, and in arithmetic expressions, the comma operator evaluates both sides, but returns just the value of the right hand side.
    – ilkkachu
    Sep 28, 2020 at 11:56
  • Thanks for the input, @ilkkachu. Let me add that to the answer.
    – Amit Singh
    Sep 28, 2020 at 11:57
0

try the following:

#!/bin/bash
read -p "Enter the size of matrix: " n
c=`expr $n - 1`

declare -A arr

# Get the matrix elements

for ((i=0;i<=c;i++))
do
        
    for ((j=0;j<=c;j++))
    do
        read -p "enter the value of $i, $j element " arr[$i,$j]
    done
done

# Print the matrix


for ((i=0;i<=c;i++))
do
    for ((j=0;j<=c;j++))
    do
            echo -n "${arr[$i,$j]} "
    done
    echo
done

Result:

$ ./matrix.sh 
Enter the size of matrix: 3
enter the value of 0, 0 element 1
enter the value of 0, 1 element 2
enter the value of 0, 2 element 3
enter the value of 1, 0 element 4
enter the value of 1, 1 element 5
enter the value of 1, 2 element 6
enter the value of 2, 0 element 7
enter the value of 2, 1 element 8
enter the value of 2, 2 element 9
1 2 3 
4 5 6 
7 8 9

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .