- 数组基础概念
什么是数组
数组是一种数据结构,用于存储多个相同类型的值。在Shell中,数组可以存储字符串、数字等数据类型
Shell数组特点
索引从0开始
可以存储不同类型的数据
大小不固定,可以动态扩展
支持稀疏数组(不连续的索引)\
- 数组声明和初始化
声明数组
方法1:直接声明
declare -a array_name
方法2:隐式声明(直接赋值)
array_name=()
初始化数组
方法1:直接赋值
fruits=("apple" "banana" "orange")
方法2:逐个元素赋值
fruits[0]="apple"
fruits[1]="banana"
fruits[2]="orange"
方法3:使用索引赋值(创建稀疏数组)
colors=([0]="red" [2]="green" [5]="blue")
方法4:从命令输出初始化
files=(*.txt)
processes=((ps aux \| awk '{print 2}'))
- 数组操作
访问数组元素
fruits=("apple" "banana" "orange")
访问单个元素
echo ${fruits[0]} # 输出: apple
echo ${fruits[1]} # 输出: banana
访问所有元素
echo ${fruits[@]} # 输出所有元素
echo ${fruits[*]} # 输出所有元素
数组长度
fruits=("apple" "banana" "orange")
数组元素个数
echo ${#fruits[@]} # 输出: 3
单个元素的长度
echo ${#fruits[0]} # 输出: 5 (apple的长度)
数组切片
fruits=("apple" "banana" "orange" "grape" "mango")
切片:从索引1开始,取2个元素
echo ${fruits[@]:1:2} # 输出: banana orange
切片:从索引2开始到结束
echo ${fruits[@]:2} # 输出: orange grape mango
数组遍历
fruits=("apple" "banana" "orange")
方法1:使用索引遍历
for ((i=0; i<${#fruits[@]}; i++)); do
echo "Element i: {fruits[i]}"
done
方法2:直接遍历元素
for fruit in "${fruits[@]}"; do
echo "Fruit: $fruit"
done
方法3:遍历索引
for index in "${!fruits[@]}"; do
echo "Index index: {fruits[index]}"
done
添加元素
fruits=("apple" "banana")
在末尾添加
fruits+=("orange")
fruits[${#fruits[@]}]="grape"
在特定位置添加(如果索引存在则替换)
fruits[1]="pear" # 替换banana为pear
删除元素
fruits=("apple" "banana" "orange")
删除特定元素
unset fruits[1] # 删除banana
echo ${fruits[@]} # 输出: apple orange
echo ${!fruits[@]} # 输出: 0 2 (索引不连续)
删除整个数组
unset fruits
- 关联数组
声明和初始化关联数组
声明关联数组(必须使用declare -A)
declare -A person
初始化
person=([name]="John" [age]="25" [city]="New York")
或者逐个赋值
person[name]="John"
person[age]="25"
person[city]="New York"
关联数组操作
declare -A person=([name]="John" [age]="25" [city]="New York")
访问元素
echo ${person[name]} # 输出: John
获取所有键
echo ${!person[@]} # 输出: name age city
获取所有值
echo ${person[@]} # 输出: John 25 New York
遍历关联数组
for key in "${!person[@]}"; do
echo "key: {person[$key]}"
done
实用示例
示例1:处理文件列表
#!/bin/bash
获取当前目录下的所有.txt文件
txt_files=(*.txt)
echo "Found ${#txt_files[@]} text files:"
for file in "${txt_files[@]}"; do
echo " - $file"
对每个文件进行操作
wc -l "$file"
done
示例2:配置参数处理
#!/bin/bash
配置文件参数
declare -A config
config=(
host\]="localhost" \[port\]="8080" \[user\]="admin" \[password\]="secret" ) # 使用配置 echo "Connecting to ${config\[host\]}:${config\[port\]}" echo "Username: ${config\[user\]}" 示例3:统计单词频率 #!/bin/bash text="apple banana apple orange banana apple" # 将文本转换为数组 words=($text) declare -A frequency # 统计频率 for word in "${words\[@\]}"; do ((frequency\[$word\]++)) done # 输出结果 for word in "${!frequency\[@\]}"; do echo "$word: ${frequency\[$word\]}" done 示例4:菜单系统 #!/bin/bash options=("Option 1" "Option 2" "Option 3" "Quit") echo "Please select an option:" select option in "${options\[@\]}"; do case $option in "Option 1") echo "You selected Option 1" ;; "Option 2") echo "You selected Option 2" ;; "Option 3") echo "You selected Option 3" ;; "Quit") break ;; \*) echo "Invalid option" ;; esac done 注意事项 引号的使用 array=("item 1" "item 2" "item 3") # 正确:保留元素中的空格 for item in "${array\[@\]}"; do echo "$item" done # 错误:元素中的空格会被分割 for item in ${array\[@\]}; do echo "$item" done original=("a" "b" "c") copy=("${original\[@\]}") # 正确复制数组 # 错误的方式(会合并所有元素) wrong_copy=(${original\[@\]})