1

I have a .txt file that has integer values written in it with a ";" separator.

117;92;16;20;

I need to compare these and select the highest one.

My code:

IFS=';' #Internat Field Separator
read -ra vector<$file
max=$vector[0]
min=$vector[0]

for i in ${vector[@]}
do

if [[ $i > $max ]] ; then
max=$i
fi

if [[ $i < $min ]] ; then
min=$i

fi
done
echo "Max value is $max, minimal value is $min"
break

The output is:

Max value is 92, minimal value is 16.

So of course this is wrong. When I try to echo it:

echo $value ( in a loop of course )

The output is

177[0] 92 16 25

Why does the first letter show as int[0]? Because of that I cannot compare them. I can't figure out anything...

8
  • 1
    max=${vector[0]}; min=${vector[0]} Commented Nov 16, 2016 at 21:22
  • If you'd checked whether it was the reading-to-an-array-from-a-file that was actually your problem before asking, you could have asked a much more focused question. Commented Nov 16, 2016 at 21:24
  • declare -p vector, by the way, is a best-practices way to print a fully known/knowable value for the variable by that name. Commented Nov 16, 2016 at 21:25
  • Hate using bash for such purposes. python -c "import sys; print(max(int(i) for i in sys.stdin.readline().split(';')))" <yourfile Commented Nov 16, 2016 at 21:27
  • 2
    @OlegAndriyanov, eh? bash is fine for the purpose, though the OP is using it exceedingly badly (for instance, they're performing ASCII string comparison, not numeric comparison). Still, the overhead of starting the Python interpreter overwhelms the shell's execution time for any reasonable list length. Commented Nov 16, 2016 at 21:28

2 Answers 2

7

Your trailing [0]s are caused by failing to use curly brackets in your parameter expansions. There's no need for them beyond clarity, anyhow -- referring to $vector expands the first element if vector is an array.

The largest issue here is that [[ $foo > $bar ]] compares these values as strings, not as numbers, hence 92 being larger than 166 (since it starts with 9 rather than 1). Use (( )) to enter a math context, in which < and > perform numeric comparisons and $ sigils are unnecessary surrounding variable names.

#!/usr/bin/env bash

IFS=';' read -ra vector <"$file"
max=${vector[0]}
min=${vector[0]}

for i in "${vector[@]}"; do
  (( i > max )) && max=$i
  (( i < min )) && min=$i
done

echo "Max value is $max, minimal value is $min"
Sign up to request clarification or add additional context in comments.

Comments

1

Improving on Charles Duffy's answer, note that the other answer's code won't work if your numbers have decimals. Code for numbers with decimals looks like this:

#!/usr/bin/env bash

IFS=';' read -ra vector <"$file"
max=${vector[0]}
min=${vector[0]}

for i in "${vector[@]}"; do
  [ $(echo "$i > $max" | bc) = 1 ] && max=$i
  [ $(echo "$i < $min" | bc) = 1 ] && min=$i
done

echo "Max value is $max, minimal value is $min"

Comments

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.