0

I am trying to print index value of maximum value in an array. I wrote something like this:

my_array=( $(cat /etc/grub.conf | grep title | cut -d " " -f 5,7 | tr -d '()'|cut -c1-6) )
echo "${my_array[*]}" | sort -nr | head -n1
max=${my_array[0]}
for v in ${my_array[@]}; do
    if (( $v > $max )); then max=$v; fi;
done
echo $max

Output of this script is coming up like:

4.9.85 4.9.38
./grub_update.sh: line 6: ((: 4.9.85 > 0 : syntax error: invalid arithmetic operator (error token is ".9.85 > 0 ")
./grub_update.sh: line 6: ((: 4.9.38 > 0 : syntax error: invalid arithmetic operator (error token is ".9.38 > 0 ")
0

Requirement: I want to query grub.conf and read Kenrnel line followed by printing index value of latest kernel in the array

kernel /boot/vmlinuz-4.9.38-16.35.amzn1.x86_64 root=LABEL=/ console=tty1 console=ttyS0 selinux=0
4
  • Bash can't compare 4.9.85 with 0... looks like you need a little more than a simple loop. Commented Mar 22, 2019 at 18:18
  • sorry, I just updated the code, currently I am able to get an output but it's throwing lower value while I am looking for greater number Commented Mar 22, 2019 at 22:53
  • If you want to do a version sort, that's what the GNU sort -V argument is for. Commented Mar 22, 2019 at 23:47
  • BTW, array=( $(...) ) is an antipattern; see BashPitfalls #50. Commented Mar 22, 2019 at 23:48

2 Answers 2

0

Comments in code:

# our array
arr=( 
     1.1.1  # first element
     2.2.2 
     4.9.85 # third element, the biggest
     4.9.38 
)

# print each array element on a separate line
printf "%s\n" "${arr[@]}" | 
# substitute the point to a space, so xargs can process it nicely
tr '.' ' ' |
# add additional zeros to handle single digit and double digit kernel versions
xargs -n3 printf "%d%02d%02d\n" |
# add line numbers as the first column
nl -w1 |
# number sort via the second column
sort -k2 -n |
# get the biggest column, the latest
tail -n1 |
# get the first field, the line/index number
cut -f1

It will output:

3

Live code available on tutorialspoint.

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

Comments

0
  • You can do string comparisons if the digits are aligned.
  • printf can align the digits
data=(
    4.9.85
    4.9.38
    3.100.20.2
    4.12.2.4.5
    4.18.3
)

findmax(){
    local cur
    local best=''
    local ans

    for v in "$@"; do
        cur="$(
            # split on dots
            IFS=.
            printf '%04s%04s%04s%04s%04s' $v
        )"
        # note: sort order is locale-dependent
        if [[ $cur > $best ]]; then
            ans="$v"
            best="$cur"
        fi
    done
    echo "$ans"
}

echo "max = $(findmax "${data[@]}")"

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.