如何在shell脚本中不使用sort cmd的情况下在数组中找到最大值

时间:2018-12-10 17:52:38

标签: shell unix

我有一个array=(4,2,8,9,1,0),并且我不想对数组进行排序以找到数组中的最高编号,因为我需要按原样获取最高编号的索引值,因此可以使用它供进一步参考。

预期输出:

 9 index value => 3

有人可以帮助我实现这一目标吗?

4 个答案:

答案 0 :(得分:2)

使用三元条件运算符的循环略有变化,并且不假设值的范围:

arr=(4 2 8 9 1 0)
max=${arr[0]}
maxIdx=0

for ((i = 1; i < ${#arr[@]}; ++i)); do
    maxIdx=$((arr[i] > max ? i : maxIdx))
    max=$((arr[i] > max ? arr[i] : max))
done

printf '%s index => values %s\n' "$maxIdx" "$max"

唯一的假设是数组索引是连续的。如果不是这样,它将变得更加复杂:

arr=([1]=4 [3]=2 [5]=8 [7]=9 [9]=1 [11]=0)
indices=("${!arr[@]}")
maxIdx=${indices[0]}
max=${arr[maxIdx]}

for i in "${indices[@]:1}"; do
    ((arr[i] <= max)) && continue
    maxIdx=$i
    max=${arr[i]}
done

printf '%s index => values %s\n' "$maxIdx" "$max"

这首先将索引放入一个单独的数组中,并将初始最大值设置为与第一个索引对应的值;然后,对索引进行迭代,跳过第一个索引(:1表示法),检查当前元素是否为新的最大值,如果是,则存储索引和最大值。

答案 1 :(得分:1)

不使用sort,就可以在shell中使用简单的循环。这是示例bash代码:

#!/usr/bin/env bash

array=(4 2 8 9 1 0)

for i in "${!array[@]}"; do
   [[ -z $max ]] || (( ${array[i]} > $max )) && { max="${array[i]}"; maxind=$i; }
done

echo "max=$max, maxind=$maxind"

max=9, maxind=3

答案 2 :(得分:1)

arr=(4 2 8 9 1 0)
paste <(printf "%s\n" "${arr[@]}") <(seq 0 $((${#arr[@]} - 1)) ) | 
sort -k1,1 | 
tail -n1 |
sed 's/\t/ index value => /'
  1. 使用printf
  2. 在换行符上打印每个数组元素
  3. 使用seq
  4. 打印数组索引
  5. 使用paste
  6. 加入两个流
  7. 使用第一字段(即数组值)sort
  8. 对行进行数字排序
  9. 打印最后一行tail -n1
  10. 数组值和结果由制表符分隔。使用sed将选项卡替换为所需的输出字符串。一个人可以使用ex。 cut -d, -f2仅获取索引或使用read a b <( ... )将数字读入变量等。

答案 3 :(得分:0)

使用Perl

$ export data=4,2,8,9,1,0
$ echo $data | perl -ne ' map{$i++; if($_>$x) {$x=$_;$id=$i} } split(","); print "max=$x", " index=",--${id},"\n" '
max=9 index=3
$