当前位置: 首页 > news >正文

Day 8:Shell数组与哈希完全指南:从“青铜“到“王者“的进化之路

目录

    • 一、索引数组:你的第一个"集合容器"
      • 1. 基础操作四连击
      • 2. 实用技巧:灵活初始化
    • 二、关联数组:让数据拥有"名字"
      • 1. 哈希表声明与使用
      • 2. 高级遍历技巧
    • 三、避坑指南:数组操作的"暗礁险滩"
      • 1. 稀疏数组陷阱
      • 2. 含空格元素的正确处理
      • 3. 数组复制陷阱
    • 四、实战:用哈希解析配置文件
    • 五、终极挑战:单词频率统计器
    • 六、性能优化:数组 vs 外部命令
      • 1. 大数据集处理对比
      • 2. 内存优化技巧
    • 课后升级挑战

开篇:当变量不再孤单

想象你是个班主任:

  • 普通变量:只能记住一个学生名字(“张三”)
  • 数组变量:能记住全班名单([“张三”,“李四”,“王五”])
  • 哈希变量:还能记住每个学生的学号({“张三”=>101, “李四”=>102})

今天我们就让Shell变量突破次元壁,解锁集合类型的超能力!

一、索引数组:你的第一个"集合容器"

1. 基础操作四连击

# 声明数组(Shell最奇葩的语法!)
fruits=("苹果" "香蕉" "橙子" "草莓")# 访问元素(从0开始)
echo ${fruits[1]}  # 输出:香蕉# 修改元素
fruits[0]="红苹果"# 获取数组长度
echo "共有 ${#fruits[@]} 种水果"

2. 实用技巧:灵活初始化

# 从命令结果创建数组
processes=($(ps -ef | awk '{print $2}'))# 序列生成(Bash 4.0+)
mapfile -t lines < /etc/passwd  # 按行读取到数组
nums=({1..10..2})  # 生成1 3 5 7 9

二、关联数组:让数据拥有"名字"

1. 哈希表声明与使用

# 必须先声明(Bash 4.0+)
declare -A student_scores# 添加键值对
student_scores=(["张三"]=90["李四"]=85["王五"]=78
)# 动态添加
student_scores["赵六"]=92# 查询
echo "张三的成绩:${student_scores["张三"]}"

2. 高级遍历技巧

# 遍历所有键
for name in "${!student_scores[@]}"; doecho "$name : ${student_scores[$name]}"
done# 按值排序输出
for k in $(echo ${!student_scores[@]} | tr ' ' '\n' | sort); doecho "$k ${student_scores[$k]}"
done

三、避坑指南:数组操作的"暗礁险滩"

1. 稀疏数组陷阱

arr=([0]="a" [3]="d")  # 中间有空位
echo "元素个数:${#arr[@]}"  # 输出2不是4!

2. 含空格元素的正确处理

# 错误示范
files=($(ls *.txt))  # 文件名含空格会分裂# 正确做法(IFS+mapfile)
IFS=$'\n' mapfile -t files < <(find . -name "*.txt")

3. 数组复制陷阱

arr1=(1 2 3)
arr2=("${arr1[@]}")  # 正确复制方式
arr3=${arr1[@]}     # 错误!变成字符串

四、实战:用哈希解析配置文件

#!/bin/bash
declare -A configparse_config() {while IFS='=' read -r key value; do[[ $key == [* ]] || continue  # 跳过注释config["${key%%[[:space:]]*}"]="${value#*[[:space:]]}"done < "app.conf"
}# 示例配置文件内容:
# [database]
# host = 127.0.0.1
# port = 3306parse_config
echo "数据库地址:${config[host]}:${config[port]}"

五、终极挑战:单词频率统计器

#!/bin/bash
declare -A word_count# 统计函数
count_words() {tr '[:upper:]' '[:lower:]' |  # 统一小写tr -cs '[:alpha:]' '\n' |    # 保留字母生成单词列表sort |uniq -c |                    # 统计频次while read count word; doword_count["$word"]=$countdone
}# 分析文本
echo "The quick brown fox jumps over the lazy dog" | count_words# 输出结果
for word in "${!word_count[@]}"; doprintf "%-10s %d\n" "$word" "${word_count[$word]}"
done | sort -k2nr  # 按频次降序

输出示例:

the        2
fox        1
dog        1
...(其他单词)

六、性能优化:数组 vs 外部命令

1. 大数据集处理对比

# 方式1:纯数组操作(更快)
for ((i=0; i<10000; i++)); doarr[$i]=$RANDOM
done# 方式2:调用外部命令(更慢)
for i in {1..10000}; doarr[$i]=$(awk 'BEGIN{print rand()}')
done

2. 内存优化技巧

# 大数组分批处理
batch_size=1000
for ((i=0; i<${#huge_array[@]}; i+=batch_size)); dobatch=("${huge_array[@]:$i:$batch_size}")process_batch "${batch[@]}"
done

课后升级挑战

任务:开发升级版词频统计工具

  • ✅ 支持从文件/管道/stdin多方式输入
  • ✅ 忽略常见停用词(the,a,an等)
  • ✅ 生成词云HTML可视化

示例效果:

$ ./wordfreq.sh < novel.txt | head -5
the      1245
love      890
time      765
...

相关文章:

  • vscode ssh远程连接到Linux并实现免密码登录
  • Zabbix干嘛的?
  • 龙虎榜——20250626
  • 创客匠人视角下创始人 IP 打造的底层逻辑与实践路径
  • 15.8 智能对话系统调试五大痛点:从多轮对话到情感识别的全场景解决方案
  • 罗马数字转整数
  • SM2、SM3、SM4算法详解
  • MySQL亿级数据平滑迁移双写方案
  • 机器学习---正则化、过拟合抑制与特征筛选
  • 数学:初步了解什么是线性代数?
  • 大一获得16届蓝桥杯国三记录
  • 七天学会SpringCloud分布式微服务——03——Nacos远程调用
  • 随记:WebMvcConfigurationSupport 和WebMvcConfigurer 的区别
  • ldl-DeserializationViewer一款强大的序列化数据可视化工具
  • 仓颉语言开发初体验HashMap,变量定义、方法定义
  • 网络安全之SQL RCE漏洞
  • 【Excel数据分析】花垣县事业单位出成绩了,用Excel自带的M语言做一个数据分析
  • 深入剖析Nginx架构及其不同使用场景下的配置
  • Ubuntu下布署mediasoup-demo
  • 【LLM安全】MCP(模型上下文协议)及其关键漏洞、技术细节