Reputation: 55
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.
Upvotes: 1
Views: 317
Reputation: 29290
$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.
Upvotes: 1
Reputation: 377
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.
Upvotes: 1