数组
# 定义
fruits=("apple" "banana" "cherry")
# 访问
echo ${fruits[0]} # apple
echo ${fruits[1]} # banana
# 长度
echo ${#fruits[@]} # 3
# 所有元素
echo "${fruits[@]}" # apple banana cherry
for f in "${fruits[@]}"; do
echo "$f"
done
# 追加
fruits+=("date")
echo "${fruits[@]}" # apple banana cherry date
# 切片
echo "${fruits[@]:1:2}" # banana cherry(从下标 1,取 2 个)
# 修改
fruits[0]="apricot"
# 删除
unset 'fruits[1]' # 删除 banana(注意单引号)
unset fruits # 删除整个数组
⚠ 引号要紧——"${fruits[@]}" 保留每个元素是独立的;不加引号会按空格切。
关联数组(Bash 4+)
declare -A user
user[name]="alice"
user[age]=30
user[email]="alice@example.com"
echo "${user[name]}" # alice
echo "${!user[@]}" # 所有键:name age email
echo "${user[@]}" # 所有值
# 遍历
for key in "${!user[@]}"; do
echo "$key = ${user[$key]}"
done
字符串长度
s="hello world"
echo ${#s} # 11
字符串截取(参数展开)
s="hello world"
# 取子串
echo ${s:6} # world(从下标 6 到末尾)
echo ${s:0:5} # hello(从 0 取 5 个)
echo ${s: -5} # world(最后 5 个,注意空格)
# 替换
echo ${s/world/bash} # hello bash (首次匹配)
echo ${s//l/L} # heLLo worLd (全部匹配)
echo ${s/#hello/Hi} # Hi world (行首匹配)
echo ${s/%world/Bash} # hello Bash (行尾匹配)
# 删除前缀
file="/path/to/file.txt"
echo ${file#*/} # path/to/file.txt (最短匹配前缀)
echo ${file##*/} # file.txt (最长匹配,等同 basename)
# 删除后缀
echo ${file%.*} # /path/to/file (最短)
echo ${file%%.*} # /path/to/file (最长,这例子结果一样)
filename="report.tar.gz"
echo ${filename%.*} # report.tar
echo ${filename%%.*} # report
echo ${filename##*.} # gz
# 大小写转换(Bash 4+)
s="Hello"
echo ${s^^} # HELLO
echo ${s,,} # hello
echo ${s^} # Hello(首字母大写)
实战:路径拆解
path="/var/log/nginx/access.log"
dir="${path%/*}"
file="${path##*/}"
name="${file%.*}"
ext="${file##*.}"
echo "目录: $dir" # /var/log/nginx
echo "文件: $file" # access.log
echo "名: $name" # access
echo "扩展名: $ext" # log
等同 dirname basename 但不需要外部命令。
实战:拆 CSV
line="alice,30,engineer"
# 用 IFS 切分
IFS=',' read -ra fields <<< "$line"
echo "${fields[0]}" # alice
echo "${fields[1]}" # 30
echo "${fields[2]}" # engineer
或:
IFS=',' read -r name age job <<< "$line"
echo "$name $age $job"
实战:批量改文件后缀
for f in *.jpeg; do
mv "$f" "${f%.jpeg}.jpg"
done
实战:从 URL 拿域名
url="https://api.example.com/v1/users"
# 去掉协议
no_proto="${url#*://}" # api.example.com/v1/users
# 域名
domain="${no_proto%%/*}" # api.example.com
# 顶级域名
tld="${domain##*.}" # com
echo "$domain / $tld"
下一篇:调试与脚本规范。