You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本优化:单次执行获取比值的最大值与最小值

问题

我有一个bash脚本,输出包含时间戳、value1、value2以及value1/value2比值的表格,示例输出如下:

2022-08-07 21:00  2784000/8750=318
2022-08-07 20:00  2792000/8760=318
2022-08-07 19:00  2790000/8760=318
2022-08-07 18:00  2776000/8750=317
2022-08-07 17:00  2804000/8570=327
2022-08-07 16:00  2799000/8580=326
2022-08-07 15:00  2783000/8590=323
2022-08-07 14:00  2729000/8580=318
2022-08-07 13:00  2638000/8530=309
2022-08-07 12:00  2637000/8490=310
2022-08-07 11:00  2610000/8450=308
2022-08-07 10:00  2595000/8470=306
2022-08-07 09:00  2616000/8490=308
2022-08-07 08:00  2604000/8470=307
2022-08-07 07:00  2619000/8450=309
2022-08-07 06:00  2626000/8530=307
2022-08-07 05:00  2627000/8530=307
2022-08-07 04:00  2634000/8530=308
2022-08-07 03:00  2626000/8470=310
2022-08-07 02:00  2625000/8530=307
2022-08-07 01:00  2676000/8540=313
2022-08-07 00:00  2654000/8590=308
2022-08-06 23:00  2673000/8610=310
2022-08-06 22:00  2641000/8570=308
2022-08-06 21:00  2655000/8610=308
2022-08-06 20:00  2665000/8670=307
2022-08-06 19:00  2672000/8670=308
2022-08-06 18:00  2626000/8680=302
2022-08-06 17:00  2581000/8690=297
2022-08-06 16:00  2581000/8720=295
2022-08-06 15:00  2560000/8720=293

目前我通过./script.sh | cut -f2,2 -d= | sort -n按等号右侧的比值进行排序,想要将最大值和最小值分别赋值给变量。虽然可以通过取首尾行来实现,但这样需要执行两次script.sh,请问是否有更高效的方法无需重复执行脚本即可获取最大值和最小值?

解决方案

方法1:用awk一次性计算最值

直接用awk遍历脚本输出的每一行,提取等号后的比值,单遍扫描中跟踪最大值和最小值,最后赋值给变量:

read min_val max_val <<< $(./script.sh | awk -F= '
    BEGIN { min = 1e18; max = -1e18 }
    {
        val = $2 + 0  # 转为数值类型
        if (val < min) min = val
        if (val > max) max = val
    }
    END { print min, max }
')

echo "最小值: $min_val"
echo "最大值: $max_val"

这种方法只执行一次script.sh,效率最高。

方法2:排序后一次性提取首尾值

如果偏好使用sort,可以把排序结果暂存,同时获取首尾行,避免重复执行脚本:

# 方式1:用awk提取排序后的首尾行
read min_val max_val <<< $(./script.sh | cut -d= -f2 | sort -n | awk 'NR==1{min=$0} END{print min, $0}')

# 方式2:把排序结果存入bash数组
sorted_vals=($(./script.sh | cut -d= -f2 | sort -n))
min_val=${sorted_vals[0]}
max_val=${sorted_vals[-1]}

方法3:纯bash循环逐行处理

如果不想依赖awk或sort,可直接用bash循环实现:

min_val=999999
max_val=0

./script.sh | while IFS='=' read -r rest val; do
    val=$((val))
    if (( val < min_val )); then
        min_val=$val
    fi
    if (( val > max_val )); then
        max_val=$val
    fi
done

echo "最小值: $min_val"
echo "最大值: $max_val"

注:若脚本输出量很大,这种纯bash循环的效率会低于awk。


内容的提问来源于stack exchange,提问作者linux_beginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 15:48:06