1

So I have the following bash script, which is supposed to read a .txt file of an n amount of integers, add it to an array, sort the array using selection sort, then print the array:

a=()
filename="$1"
while IFS='' read -r line || [[ -n "$line" ]]; do
    a+=($line)
done < "$filename"

for((i=0; i<${#a[@]}; i++))
do
  min=$i
  for((j=$i+1; j<${#a[@]}; j++))
  do
    if (( ${a[$j]} <= ${a[$min]} ))
    then
      $min=$j
      echo "$min"
    fi
  done
  temp=a[$i]
  a[$i]=a[$min]
  a[$min]=$temp
done

for i in ${a[@]}
do
  echo $i
done

The problem is that the conditional within the inner loop throws an exception, where the problem I believe is that the array elements are all strings, and I'm not sure how to cast them to strings in this situation. Also, I don't think I'm swapping the two values properly. The output:

sh selectionsort.sh 10.txt
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 152ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 436ax error: invalid arithmetic operator (error token is "
 ") 756ax error: invalid arithmetic operator (error token is "
 ") 756ax error: invalid arithmetic operator (error token is "
 ") 756ax error: invalid arithmetic operator (error token is "
 ") 756ax error: invalid arithmetic operator (error token is "
 ") 756ax error: invalid arithmetic operator (error token is "
 ") 756ax error: invalid arithmetic operator (error token is "
 ") 756ax error: invalid arithmetic operator (error token is "
 ") 391ax error: invalid arithmetic operator (error token is "
 ") 391ax error: invalid arithmetic operator (error token is "
 ") 391ax error: invalid arithmetic operator (error token is "
 ") 391ax error: invalid arithmetic operator (error token is "
 ") 391ax error: invalid arithmetic operator (error token is "
 ") 391ax error: invalid arithmetic operator (error token is "
 ") 435ax error: invalid arithmetic operator (error token is "
 ") 435ax error: invalid arithmetic operator (error token is "
 ") 435ax error: invalid arithmetic operator (error token is "
 ") 435ax error: invalid arithmetic operator (error token is "
 ") 435ax error: invalid arithmetic operator (error token is "
 ") 404ax error: invalid arithmetic operator (error token is "
 ") 404ax error: invalid arithmetic operator (error token is "
 ") 404ax error: invalid arithmetic operator (error token is "
 ") 404ax error: invalid arithmetic operator (error token is "
 ") 853ax error: invalid arithmetic operator (error token is "
 ") 853ax error: invalid arithmetic operator (error token is "
 ") 853ax error: invalid arithmetic operator (error token is "
 ") 278ax error: invalid arithmetic operator (error token is "
 ") 278ax error: invalid arithmetic operator (error token is "
 ") 643ax error: invalid arithmetic operator (error token is "
a[0]
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
a[7]
a[8]
a[9]

Any help is appreciated! Note: I know there's easier way to sort arrays, I'm using this script to implement selection sort.

2
  • selection sort in bash? how would you expect people to answer your question? Commented Oct 29, 2017 at 2:52
  • It's jut an implementation, the sort itself is not the issue; it's the read from the file I believe and the conditional. Commented Oct 29, 2017 at 3:09

2 Answers 2

1

$min=$j is definitely an error. It should be min=$j. The way you access the cells of your array (temp=a[$i], a[$i]=a[$min]) too. Use temp=${a[$i]}, a[$i]=${a[$min]}, instead. But there are a few more things that you could improve:

declare -ai a=()
declare -i i j min temp
declare line

filename="$1"
while IFS='' read -r line; do
  [[ $line =~ ^[0-9]+$ ]] && a+=($line) || printf "Warning: not a number (%s)\n" "$line"
done < "$filename"

for (( i=0; i<${#a[@]}; i++ ))
do
  min=$i
  for (( j=i+1; j<${#a[@]}; j++ ))
  do
    if (( a[j] <= a[min] ))
    then
      min=$j
      echo "$min"
    fi
  done
  temp=${a[i]}
  a[i]=${a[min]}
  a[min]=$temp
done

for i in "${a[@]}"
do
  echo "$i"
done

In the context of arithmetic evaluation (((...))) and array indexing (a[...]), variable names are interpreted as their numeric values (no need of $).

I also added variable declarations and a test to eliminate non-integer entries.

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

5 Comments

Thanks! I'm still confused on why it's not $min =$j. I've declared min prior to this line, don't you always need to put a $ when accessing variables that were already initialized?
min is the variable name.$min is its value.
And don't we need to change it's value by saying $min rather than min? F.e. a=5, b=1, $a=2, $a=$b is how we change the value of variables, from what I've learned.
If the value of min is 5 and you execute $min=6 the expansion transforms it into 5=6 and you get an error message because it does not make sense. Think at $x as value(x) and x as the name of the variable.
Oh! so $ is similar to the concept of dereferencing a pointer in C, at least that's how I'm understanding it. Thanks!
1

If you are using bash you can take advantage of its builtin functions like sort and readarray. (notice readarray is available since bash 4+, no OS X support by default.)

You can remove your sorting code and use the following code as described here

readarray -t sorted < <(for b in "${a[@]}"; do echo "$b"; done | sort)

$a will be transformed to a sorted array.

6 Comments

The point of this script is just to implement the selection sort algorithm using the shell. I know it can be done in an easier method, my only question is what the issue is with the current script.
I ran it and it worked, the only problem I might figure is $min=$j should be min=$j
Why would you not put the $? I initialized it prior.
In my bash version it failed with ./test.sh: line 15: 2=3: command not found, I was assigning an int to an int
The initialization of the for loop? There seems to be no issue there.
|

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.