Home > OS >  Returning index of the maximum value in an array - bash
Returning index of the maximum value in an array - bash

Time:11-15

Given a file with an input in the format of (longitude,latitude,date,time,temperature), write a bash script that returns the place and time of the highest measured temperature on the list.

Example input:

53.0382,96.5753,2010.11.16.,07:23,38
53.0382,96.5753,2000.06.21.,09:05,-16
53.0382,96.5753,2007.05.16.,02:00,-4
53.0382,96.5753,2008.07.27.,22:38,-6
53.0382,96.5753,2001.07.09.,09:50,-12
53.0382,96.5753,2016.12.08.,22:55,28

Example output:

The highest measured temperature was 38 degrees on 2010.11.16. at 07:23. it was measured at the coordinates of 53.0382, 96.5753

I've written a script that successfully takes the input and splits it into different arrays for each of the different values given. I was trying to loop through the temperatures to find the index of the highest one, using it to index the date,time,and location arrays for the output.

#!/bin/bash
latitude=(); longitude=(); date=(); time=(); value=();
while IFS=, read -ra arr;
do
    latitude =(${arr[0]})
    longitude =(${arr[1]})
    date =(${arr[2]})
    time =(${arr[3]})
    value =(${arr[4]})
done < temperatures.txt
max=0
maxI=0
count=$(wc -l <temperatures.txt)
for ((i=0; i<$count; i  )) ;
do
echo ${value[i]}
    if ((${value[i]} > $max)) ; then
        max=${value[i]}
        maxI=$i
    fi
done
echo $max
echo $maxI

With the above code, I get the error syntax error: invalid arithmetic operator (error token is " > 0"). It seems to be a problem with line 17, the if statement. I'd appreciate it if anyone could shed some light on what my problem is.

CodePudding user response:

Skip the array and just keep track of the highest temp (and associated values), eg;

temp=-1000

while IFS=, read -r a b c d e
do
    [[ "${e}" -gt "${temp}" ]] &&
    long="${a}"                &&
    lat="${b}"                 &&
    tdate="${c}"               &&
    ttime="${d}"               &&
    temp="${e}"
done < temperatures.txt

printf "The highest measured temperature was %s degrees on %s at %s. It was measured at the coordinates of %s, %s\n" "${temp}" "${tdate}" "${ttime}" "${long}" "${lat}"

This generates:

The highest measured temperature was 38 degrees on 2010.11.16. at 07:23. It was measured at the coordinates of 53.0382, 96.5753

For processing a large volume of rows I'd probably opt for something like awk (for performance reasons), eg:

awk -F, '
$5 > temp { long=$1; lat=$2; tdate=$3; ttime=$4; temp=$5 }
END       { printf "The highest measured temperature was %s degrees on %s at %s. It was measured at the coordinates of %s, %s\n", temp, tdate, ttime, long, lat }
' temperatures.txt

CodePudding user response:

I don't get the error you are speaking about. Try:

#!/bin/bash
latitude=(); longitude=(); date=(); time=(); value=()
while IFS=, read -ra arr;
do
    latitude =(${arr[0]})
    longitude =(${arr[1]})
    date =(${arr[2]})
    time =(${arr[3]})
    value =(${arr[4]})
    (( count   ))
done < temperatures.txt
max=-100
maxI=0
for ((i=0; i<$count; i  )) ;
do
    if ((${value[i]} > $max)) ; then
        max=${value[i]}
        maxI=$i
    fi
done
echo -n "The highest measured temperature was ${value[$maxI]} degrees"
echo -n " on ${date[$maxI]} at ${time[$maxI]}."
echo -n " It was measured at the coordinates of"
echo " ${latitude[$maxI]}, ${longitude[$maxI]}"

Instead of invoking wc -l for counting the number of input lines, which implies to read the whole input file a second time, I just increment the counter each time an input line is read.

I initialize max to -100 in order to make this script work in case of all negative temperatures.

CodePudding user response:

Not a solution to your bug, but a better solution to the problem.

sort -nt, -k5,5 temperatures.txt |
tail -n 1 |
awk -F , '{print ("The highest measured temperature was "$5 \
           " degrees on "$3" at "$4". It was measured at the" \
           " coordinates of "$1", "$2".")}'
  •  Tags:  
  • bash
  • Related