简体   繁体   中英

sorting numbers read in from input file in bash

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.

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.

$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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM