Bash脚本开发:按身高体重统计运动员数据并确定优势国籍
问题描述
需要开发一个Bash脚本,满足以下要求:
- 脚本接收身高、体重两个参数
- 处理
athletes.csv文件(表头:id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info) - 实现三个功能:
- 统计同时匹配指定身高和体重的运动员数量
- 找出这些运动员中占比最高的国籍
- 若多个国籍占比相同,选择对应ID最小的国籍
- 禁止使用
awk、grep、sed或csvkit工具
目前已完成统计匹配数量的代码,但无法实现“找出最常见国籍”的功能,需要技术帮助。现有代码如下:
count=0 while IFS=, read -a id _ nation _ _ height weight _ _ _ _; do if (( $height == "$2" )) && (( "$weight" == $3 )) ; then ((count++)) fi done < athletes.csv echo "$count"
解决方案
问题分析
原代码存在两个核心问题:
read -a是将整行内容存入数组,不能直接用id _ nation这种方式拆分变量,会导致字段读取错误- 使用
(( ))进行数值比较仅适用于整数,而CSV中的身高、体重是浮点格式,会触发语法错误
完整实现代码
#!/bin/bash # 检查参数数量 if [ $# -ne 2 ]; then echo "用法: $0 <身高> <体重>" exit 1 fi target_height="$1" target_weight="$2" declare -A nation_count # 存储每个国籍的匹配人数 declare -A nation_min_id # 存储每个国籍对应的最小运动员ID total_matched=0 # 读取CSV文件,跳过表头 read -r header # 读取第一行表头并丢弃 while IFS=, read -r id name nationality sex dob height weight sport gold silver bronze info; do # 匹配身高和体重(字符串精确匹配,确保与CSV格式一致) if [ "$height" = "$target_height" ] && [ "$weight" = "$target_weight" ]; then ((total_matched++)) # 更新国籍计数 ((nation_count["$nationality"]++)) # 更新最小ID:如果该国籍未记录ID,或当前ID更小,则替换 if [ -z "${nation_min_id["$nationality"]}" ] || [ "$id" -lt "${nation_min_id["$nationality"]}" ]; then nation_min_id["$nationality"]="$id" fi fi done < athletes.csv # 输出匹配总数 echo "匹配指定身高体重的运动员数量: $total_matched" # 处理无匹配的情况 if [ $total_matched -eq 0 ]; then echo "无符合条件的运动员" exit 0 fi # 找出占比最高的国籍 max_count=0 top_nation="" top_min_id="" for nation in "${!nation_count[@]}"; do current_count="${nation_count[$nation]}" current_min_id="${nation_min_id[$nation]}" # 比较计数:如果当前计数更大,直接更新 if [ "$current_count" -gt "$max_count" ]; then max_count="$current_count" top_nation="$nation" top_min_id="$current_min_id" # 计数相同时,比较最小ID,选ID更小的国籍 elif [ "$current_count" -eq "$max_count" ]; then if [ "$current_min_id" -lt "$top_min_id" ]; then top_nation="$nation" top_min_id="$current_min_id" fi fi done echo "占比最高的国籍: $top_nation (人数: $max_count, 最小ID: $top_min_id)"
代码说明
- 参数校验:先检查传入参数数量是否为2,避免错误调用
- 数组初始化:用两个关联数组分别记录国籍的匹配人数和最小ID
- CSV读取:用
read -r配合明确的变量列表拆分字段,确保每个字段正确对应;先读取表头并跳过 - 匹配逻辑:用字符串精确匹配身高体重(确保与CSV中的浮点格式完全一致)
- 统计与更新:每匹配到一个运动员,更新对应国籍的计数,同时维护该国籍的最小ID
- 结果计算:遍历统计数组,找出计数最高的国籍;若计数相同,通过最小ID筛选最终结果
内容的提问来源于stack exchange,提问作者Brian_stt
相关产品推荐
相关产品推荐

