跳转到内容

Shell数组操作

课程介绍

数组是Shell脚本中用于存储多个值的变量。本课程将详细讲解Shell数组的定义、初始化、访问、遍历、操作等核心功能,帮助你掌握Shell数组的使用技巧。

1. 数组概述

1.1 什么是数组

数组是一种用于存储多个值的变量,每个值都有一个索引。

数组的特点

特点说明
存储多个值可以存储多个值
索引访问通过索引访问值
动态大小数组大小可以动态变化
类型灵活可以存储不同类型的值

1.2 数组的类型

Shell支持两种类型的数组。

数组类型

类型说明
索引数组使用数字索引
关联数组使用字符串索引

2. 索引数组

2.1 定义数组

定义索引数组的方法。

示例1:定义数组

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 定义带索引的数组
fruits=([0]="apple" [1]="banana" [2]="orange")

# 逐个定义数组元素
fruits[0]="apple"
fruits[1]="banana"
fruits[2]="orange"

示例2:定义数字数组

bash
# 定义数字数组
numbers=(1 2 3 4 5)

# 定义带索引的数字数组
numbers=([0]=1 [1]=2 [2]=3 [3]=4 [4]=5)

示例3:定义混合数组

bash
# 定义混合数组
mixed=("apple" 123 "orange" 456)

2.2 访问数组元素

访问数组元素的方法。

示例1:访问单个元素

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 访问第一个元素
echo ${fruits[0]}

# 访问第二个元素
echo ${fruits[1]}

# 访问第三个元素
echo ${fruits[2]}

示例2:访问所有元素

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 访问所有元素
echo ${fruits[@]}

# 访问所有元素(另一种方式)
echo ${fruits[*]}

示例3:访问数组长度

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 访问数组长度
echo ${#fruits[@]}

# 访问数组长度(另一种方式)
echo ${#fruits[*]}

2.3 遍历数组

遍历数组元素的方法。

示例1:使用for循环遍历

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 使用for循环遍历
for fruit in "${fruits[@]}"
do
    echo "水果:$fruit"
done

示例2:使用索引遍历

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 使用索引遍历
for i in "${!fruits[@]}"
do
    echo "索引:$i,水果:${fruits[$i]}"
done

示例3:使用while循环遍历

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 使用while循环遍历
i=0
while [ $i -lt ${#fruits[@]} ]
do
    echo "索引:$i,水果:${fruits[$i]}"
    i=$((i+1))
done

2.4 添加元素

向数组添加元素的方法。

示例1:添加元素到末尾

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 添加元素到末尾
fruits+=("grape")

# 查看数组
echo ${fruits[@]}

示例2:添加元素到指定位置

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 添加元素到指定位置
fruits[3]="grape"

# 查看数组
echo ${fruits[@]}

2.5 删除元素

从数组删除元素的方法。

示例1:删除指定元素

bash
# 定义数组
fruits=("apple" "banana" "orange" "grape")

# 删除指定元素
unset fruits[2]

# 查看数组
echo ${fruits[@]}

示例2:删除整个数组

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 删除整个数组
unset fruits

# 查看数组
echo ${fruits[@]}

2.6 修改元素

修改数组元素的方法。

示例1:修改指定元素

bash
# 定义数组
fruits=("apple" "banana" "orange")

# 修改指定元素
fruits[1]="pear"

# 查看数组
echo ${fruits[@]}

3. 关联数组

3.1 定义关联数组

定义关联数组的方法。

示例1:定义关联数组

bash
# 声明关联数组
declare -A user

# 定义关联数组
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 逐个定义关联数组元素
user[name]="张三"
user[age]="25"
user[email]="zhangsan@example.com"

示例2:定义配置关联数组

bash
# 声明关联数组
declare -A config

# 定义配置关联数组
config=([host]="localhost" [port]="3306" [user]="root" [password]="password")

3.2 访问关联数组元素

访问关联数组元素的方法。

示例1:访问单个元素

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 访问name元素
echo ${user[name]}

# 访问age元素
echo ${user[age]}

# 访问email元素
echo ${user[email]}

示例2:访问所有元素

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 访问所有元素
echo ${user[@]}

# 访问所有元素(另一种方式)
echo ${user[*]}

示例3:访问所有键

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 访问所有键
echo ${!user[@]}

# 访问所有键(另一种方式)
echo ${!user[*]}

3.3 遍历关联数组

遍历关联数组元素的方法。

示例1:遍历所有键

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 遍历所有键
for key in "${!user[@]}"
do
    echo "键:$key,值:${user[$key]}"
done

示例2:遍历所有值

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 遍历所有值
for value in "${user[@]}"
do
    echo "值:$value"
done

3.4 添加元素

向关联数组添加元素的方法。

示例1:添加元素

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 添加元素
user[phone]="13800138000"

# 查看数组
for key in "${!user[@]}"
do
    echo "键:$key,值:${user[$key]}"
done

3.5 删除元素

从关联数组删除元素的方法。

示例1:删除指定元素

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 删除指定元素
unset user[age]

# 查看数组
for key in "${!user[@]}"
do
    echo "键:$key,值:${user[$key]}"
done

3.6 修改元素

修改关联数组元素的方法。

示例1:修改指定元素

bash
# 定义关联数组
declare -A user
user=([name]="张三" [age]="25" [email]="zhangsan@example.com")

# 修改指定元素
user[age]="26"

# 查看数组
for key in "${!user[@]}"
do
    echo "键:$key,值:${user[$key]}"
done

4. 数组操作

4.1 数组切片

数组切片用于获取数组的子集。

示例1:获取数组的子集

bash
# 定义数组
fruits=("apple" "banana" "orange" "grape" "pear")

# 获取前3个元素
echo ${fruits[@]:0:3}

# 获取从第2个元素开始的2个元素
echo ${fruits[@]:1:2}

# 获取从第3个元素开始的所有元素
echo ${fruits[@]:2}

4.2 数组拼接

数组拼接用于合并多个数组。

示例1:拼接两个数组

bash
# 定义两个数组
fruits1=("apple" "banana")
fruits2=("orange" "grape")

# 拼接两个数组
fruits=("${fruits1[@]}" "${fruits2[@]}")

# 查看数组
echo ${fruits[@]}

4.3 数组排序

数组排序用于对数组元素进行排序。

示例1:对数组进行排序

bash
# 定义数组
numbers=(5 3 1 4 2)

# 对数组进行排序
sorted_numbers=($(echo "${numbers[@]}" | tr ' ' '\n' | sort -n | tr '\n' ' '))

# 查看排序后的数组
echo ${sorted_numbers[@]}

4.4 数组去重

数组去重用于删除数组中的重复元素。

示例1:对数组进行去重

bash
# 定义数组
numbers=(1 2 3 2 4 3 5)

# 对数组进行去重
unique_numbers=($(echo "${numbers[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))

# 查看去重后的数组
echo ${unique_numbers[@]}

4.5 数组查找

数组查找用于在数组中查找特定元素。

示例1:查找元素

bash
# 定义数组
fruits=("apple" "banana" "orange" "grape")

# 查找元素
for i in "${!fruits[@]}"
do
    if [ "${fruits[$i]}" == "orange" ]; then
        echo "找到元素:orange,索引:$i"
    fi
done

5. 完整示例

示例1:配置文件解析

bash
#!/bin/bash
# 配置文件解析

# 定义关联数组
declare -A config

# 解析配置文件
while read line
do
    # 跳过空行和注释行
    if [[ -z "$line" || "$line" == \#* ]]; then
        continue
    fi
    
    # 解析配置项
    key=$(echo "$line" | cut -d'=' -f1)
    value=$(echo "$line" | cut -d'=' -f2)
    
    # 去除空格
    key=$(echo "$key" | xargs)
    value=$(echo "$value" | xargs)
    
    # 保存到关联数组
    config[$key]=$value
done < config.ini

# 查看配置
for key in "${!config[@]}"
do
    echo "配置项:$key = ${config[$key]}"
done

示例2:日志分析

bash
#!/bin/bash
# 日志分析

# 定义关联数组
declare -A log_count

# 分析日志文件
while read line
do
    # 提取日志级别
    log_level=$(echo "$line" | grep -oE "ERROR|WARN|INFO")
    
    # 统计日志级别
    if [ -n "$log_level" ]; then
        log_count[$log_level]=$((${log_count[$log_level]} + 1))
    fi
done < /var/log/syslog

# 查看统计结果
for log_level in "${!log_count[@]}"
do
    echo "日志级别:$log_level,数量:${log_count[$log_level]}"
done

示例3:批量处理文件

bash
#!/bin/bash
# 批量处理文件

# 定义数组
files=("file1.txt" "file2.txt" "file3.txt")

# 遍历文件
for file in "${files[@]}"
do
    # 检查文件是否存在
    if [ -f "$file" ]; then
        # 处理文件
        echo "处理文件:$file"
        
        # 统计行数
        lines=$(wc -l < "$file")
        echo "  行数:$lines"
        
        # 统计字数
        words=$(wc -w < "$file")
        echo "  字数:$words"
    else
        echo "文件不存在:$file"
    fi
done

课程总结

这节课我们学习了Shell数组操作。

核心内容:

  • 数组概述
  • 索引数组(定义、访问、遍历、添加、删除、修改)
  • 关联数组(定义、访问、遍历、添加、删除、修改)
  • 数组操作(切片、拼接、排序、去重、查找)
  • 完整示例

重要概念:

  • 索引数组:使用数字索引的数组
  • 关联数组:使用字符串索引的数组
  • 数组遍历:使用for循环遍历数组
  • 数组操作:切片、拼接、排序、去重、查找

数组是Shell脚本编程的重要工具,掌握这些知识后,我们将在后续课程中学习脚本调试技巧、自动化备份脚本实战等内容。

课后练习

练习1(基础)

创建一个索引数组,包含5个水果名称,并遍历输出。

练习2(进阶)

创建一个关联数组,包含用户信息(name、age、email),并遍历输出。

练习3(拓展)

编写一个脚本,分析日志文件,统计不同日志级别的数量。

评论区

专业的Linux技术学习平台,从入门到精通的完整学习路径