0
votes

I have a test file that looks like this:

1   1   1   1   1
9   3   4   5   5
6   7   8   9   7
3   6   8   9   1
3   4   2   1   4
6   4   4   7   7

Each row is supposed to represent a students grades. So the user puts in either an 'r' or a 'c' into the command line to choose to sort by rows or columns, followed by the file name. Sorting by rows would represent getting a students average and sorting my columns would represent a particular assignments average.

I am not doing anything with the choice variable yet because I need to get the array sorted first so I can take the averages and then get the median for each column and row.

So im not sure how I can choose to sort by those specific options. Here is what I have so far:

#!/bin/bash
choice="$1"
filename="$2"
c=0
if [ -e "$filename" ]
then
      while read line
      do
         myArray[$c]=$line
         c=$(expr $c + 1)
         done < "$filename"
 else
     echo "File does not exist"
fi
printf -- '%s\n' "${myArray[@]}"
FS=$'\n' sorted=($(sort -n -k 1,1<<<"${myArray[*]}"))
echo " "
printf '%s\n' "${sorted[@]}"

This is only sorting the first column though and im not sure why its even doing that. Any push in the right direction would be appreciated. Examples would help a ton, thanks!

UPDATE: With the changes that were suggested I have this so far:

#!/bin/sh

IFS=$'\n';

choice="$1"

filename="$2"

if [ -e "$filename" ]

then
        while read line

        do
                myArray[$c]=$line

                c=$(expr $c + 1)

        done < "$filename"

else
        echo "File does not exist."
fi

printf -- '%s\n' "${myArray[@]}"

width=${myArray[0]// /}

width=${#width}

height=${#myArray[@]}

bar=()

for w in $(seq 0 1 $((${width}-1)))

do
        tmp=($(sort -n <<<"${myArray[*]}"))

        for h in $(seq 0 1 $((${height}-1)))

        do
                myArray[h]=${myArray[h]#* }

                bar[h]="${bar[h]} ${tmp[h]%% *}"

                bar[h]="${bar[h]# }"

        done
done

printf -- '%s\n' "${bar[*]}"

But now I am getting some really strange output of way more numbers than i started with and in a seemingly random order.

1

1 Answers

0
votes

actually it is sorting $line(s) which are strings. you need to initialize the column to sort correctly, so that it is an array

UPDATE:

the following code is really straight forward. no performance aspects are regarded. so for large datasets this will take a while to sort column wise. your datasets have to contain lines of numbers seperated by single spaces to make this work.

#!/bin/bash

IFS=$'\n';

# here you can place your read line function
ar[0]="5 3 2 8"
ar[1]="1 1 1 1"
ar[2]="3 2 4 5"
printf -- '%s\n' "${ar[*]}" # print the column wise unsorted ar
echo

# sorting
width=${ar[0]// /}
width=${#width}
height=${#ar[@]}

bar=()
for w in $(seq 0 1 $((${width}-1))); do # for each column
  #sort -n <<<"${ar[*]}" # debug, see first column removal
  tmp=($(sort -n <<<"${ar[*]}")) # this just sorts lexigraphically by "first column"
                                 # rows are strings, see initial definition of ar
  #echo
  for h in $(seq 0 1 $((${height}-1))); do # update first column
    ar[h]=${ar[h]#* } # strip first column
    bar[h]="${bar[h]} ${tmp[h]%% *}" # add sorted column to new array
    bar[h]="${bar[h]# }" # trim leading space
  done
  #printf -- '%s\n' "${bar[*]}" # debug, see growing bar
  #echo "---"
done

printf -- '%s\n' "${bar[*]}" # print the column wise sorted ar

prints out the unsorted and sorted array

5 3 2 8
1 1 1 1
3 2 4 5

1 1 1 1
3 2 2 5
5 3 4 8