Appearance
数组操作
本节介绍 Shell 数组的进阶操作,包括遍历、过滤、排序和关联数组的高级用法。
数组复制
bash
original=(1 2 3 4 5)
# 完整复制
copy=("${original[@]}")
# 验证
echo "${copy[@]}" # 1 2 3 4 5数组合并
bash
arr1=(a b c)
arr2=(d e f)
# 合并两个数组
merged=("${arr1[@]}" "${arr2[@]}")
echo "${merged[@]}" # a b c d e f添加与删除元素
bash
arr=(a b c)
# 追加元素
arr+=(d e)
echo "${arr[@]}" # a b c d e
# 删除指定元素(通过 unset)
unset arr[2] # 删除索引 2(c)
echo "${arr[@]}" # a b d e(索引出现空洞)
echo "${arr[*]}" # a b d e
# 重建数组(消除空洞)
arr=("${arr[@]}")
echo "${!arr[@]}" # 0 1 2 3(连续索引)
# 删除最后一个元素
unset 'arr[-1]'数组切片
bash
arr=(a b c d e f g)
# 从索引 2 开始取 3 个元素
echo "${arr[@]:2:3}" # c d e
# 从索引 4 开始到末尾
echo "${arr[@]:4}" # e f g数组遍历
bash
arr=("apple" "banana" "cherry")
# 遍历元素
for item in "${arr[@]}"; do
echo "$item"
done
# 遍历索引
for i in "${!arr[@]}"; do
echo "[$i] ${arr[$i]}"
done
# C 风格遍历
for (( i=0; i<${#arr[@]}; i++ )); do
echo "[$i] ${arr[$i]}"
done数组过滤
bash
#!/bin/bash
arr=(1 2 3 4 5 6 7 8 9 10)
# 过滤出偶数
evens=()
for n in "${arr[@]}"; do
(( n % 2 == 0 )) && evens+=("$n")
done
echo "偶数:${evens[@]}" # 2 4 6 8 10
# 过滤包含特定字符串的元素
words=("apple" "apricot" "banana" "avocado")
filtered=()
for w in "${words[@]}"; do
[[ "$w" == a* ]] && filtered+=("$w")
done
echo "以 a 开头:${filtered[@]}" # apple apricot avocado数组排序
bash
#!/bin/bash
arr=(3 1 4 1 5 9 2 6)
# 升序排序
sorted=($(echo "${arr[@]}" | tr ' ' '\n' | sort -n))
echo "升序:${sorted[@]}" # 1 1 2 3 4 5 6 9
# 降序排序
sorted_desc=($(echo "${arr[@]}" | tr ' ' '\n' | sort -rn))
echo "降序:${sorted_desc[@]}"
# 字符串数组排序
words=("banana" "apple" "cherry")
sorted_words=($(echo "${words[@]}" | tr ' ' '\n' | sort))
echo "排序:${sorted_words[@]}" # apple banana cherry数组去重
bash
#!/bin/bash
arr=(1 2 3 2 4 3 5 1)
# 使用关联数组去重
declare -A seen
unique=()
for item in "${arr[@]}"; do
if [[ -z "${seen[$item]+x}" ]]; then
unique+=("$item")
seen[$item]=1
fi
done
echo "去重:${unique[@]}" # 1 2 3 4 5关联数组(字典)操作
bash
#!/bin/bash
declare -A user
user["name"]="张三"
user["age"]=25
user["city"]="北京"
# 访问
echo "${user["name"]}"
# 遍历键值对
for key in "${!user[@]}"; do
echo "$key = ${user[$key]}"
done
# 检查键是否存在
if [[ -v user["name"] ]]; then
echo "name 键存在"
fi
# 删除键
unset user["age"]
echo "删除 age 后:${!user[@]}"
# 获取所有键
echo "所有键:${!user[@]}"
# 获取所有值
echo "所有值:${user[@]}"实用示例
实现栈(Stack)
bash
#!/bin/bash
stack=()
push() { stack+=("$1"); }
pop() {
[ ${#stack[@]} -eq 0 ] && return 1
echo "${stack[-1]}"
unset 'stack[-1]'
}
peek() { echo "${stack[-1]}"; }
push "a"; push "b"; push "c"
echo "栈顶:$(peek)" # c
echo "弹出:$(pop)" # c
echo "当前栈:${stack[@]}" # a b实现队列(Queue)
bash
#!/bin/bash
queue=()
enqueue() { queue+=("$1"); }
dequeue() {
[ ${#queue[@]} -eq 0 ] && return 1
echo "${queue[0]}"
queue=("${queue[@]:1}")
}
enqueue "first"
enqueue "second"
enqueue "third"
echo "出队:$(dequeue)" # first
echo "当前队列:${queue[@]}" # second third统计词频
bash
#!/bin/bash
text="apple banana apple cherry banana apple"
declare -A freq
for word in $text; do
(( freq[$word]++ ))
done
for word in "${!freq[@]}"; do
echo "$word: ${freq[$word]}"
done
# apple: 3
# banana: 2
# cherry: 1