如何找出Bash数组与指定数值范围的共同元素
解决Shell数组与数值范围/列表的交集问题
嘿,我来帮你搞定这个Shell数组筛选的需求~ 注意到你写的range变量内容没写完(只到range=9...),我会针对两种最常见的场景给出解决方案,你可以根据实际的range格式来选用:
场景1:range是连续数值区间(比如900到1400)
如果你的range是类似min...max这样的连续数值范围,我们可以先解析出区间的上下限,再遍历数组判断每个元素是否在区间内。
完整可运行脚本
#!/bin/bash # 你的原始数组定义 number1=(1220 1374 415 1097 1219 557 401 1230 1363 1116 1109 1244 571 1347 1404) number2=(411 1101 273 1217 547 1370 286 1224 1362 1091 567 561 1348 1247 1106 304 435 317) # 这里补全range为连续区间,比如900到1400 range="900...1400" # 拆分range得到最小值和最大值 IFS='...' read -r min_val max_val <<< "$range" # 写个通用的筛选函数,方便复用 filter_in_range() { local target_array=("$@") local matched_nums=() for num in "${target_array[@]}"; do # 用整数比较判断是否在区间内 if (( num >= min_val && num <= max_val )); then matched_nums+=("$num") fi done echo "${matched_nums[@]}" } # 输出结果 echo "number1中落在range区间内的数值:" filter_in_range "${number1[@]}" echo -e "\nnumber2中落在range区间内的数值:" filter_in_range "${number2[@]}"
脚本小说明
- 用
IFS='...'把range字符串拆成最小值和最大值,这样不管你实际的区间是多少,只要格式是a...b就能正常解析。 - 定义的
filter_in_range函数可以复用,不管是给number1还是number2筛选都能用,减少重复代码。 - 整数比较用
(( ... ))语法,简洁又可靠。
场景2:range是离散数值列表(比如900 1097 1220...)
如果你的range是一堆离散的数值(比如某个特定的数值集合),我们可以把range转成哈希表(关联数组)来加快查找速度,然后遍历数组判断元素是否在列表里。
完整可运行脚本
#!/bin/bash # 你的原始数组定义 number1=(1220 1374 415 1097 1219 557 401 1230 1363 1116 1109 1244 571 1347 1404) number2=(411 1101 273 1217 547 1370 286 1224 1362 1091 567 561 1348 1247 1106 304 435 317) # 这里补全range为离散数值数组 range=(900 1097 1220 1374 1101 1217) # 通用筛选函数 filter_in_list() { local target_array=("$@") # 把range转成关联数组,这样查找元素是O(1),比循环遍历快很多 declare -A range_hash for r_num in "${range[@]}"; do range_hash["$r_num"]=1 done # 遍历目标数组,收集匹配的数值 local matched_nums=() for num in "${target_array[@]}"; do if [[ -n "${range_hash[$num]}" ]]; then matched_nums+=("$num") fi done echo "${matched_nums[@]}" } # 输出结果 echo "number1中存在于range列表的数值:" filter_in_list "${number1[@]}" echo -e "\nnumber2中存在于range列表的数值:" filter_in_list "${number2[@]}"
脚本小说明
- 关联数组
range_hash相当于一个字典,把range里的数值作为键,这样判断某个数是否在range里时,直接查键是否存在就行,比每次循环遍历range数组效率高很多,尤其是当range很大的时候。 - 同样用了通用函数,复用性拉满~
运行效果参考
如果是场景1(range=900...1400),运行后会输出:
number1中落在range区间内的数值: 1220 1374 1097 1219 1230 1363 1116 1109 1244 1347 1404 number2中落在range区间内的数值: 1101 1217 1370 1224 1362 1091 1348 1247 1106
如果是场景2(range=(900 1097 1220 1374 1101 1217)),运行后会输出:
number1中存在于range列表的数值: 1220 1374 1097 number2中存在于range列表的数值: 1101 1217
内容的提问来源于stack exchange,提问作者flash
相关产品推荐
相关产品推荐

