for循环 #

一、for循环基础 #

1.1 基本语法 #

bash
# 列表形式
for 变量 in 列表; do
    命令
done

# C风格形式
for (( 初始化; 条件; 更新 )); do
    命令
done

1.2 简单示例 #

bash
#!/bin/bash

# 遍历列表
for fruit in apple banana cherry; do
    echo "水果: $fruit"
done

# 遍历数组
fruits=("苹果" "香蕉" "橙子")
for fruit in "${fruits[@]}"; do
    echo "水果: $fruit"
done

# C风格循环
for (( i=1; i<=5; i++ )); do
    echo "计数: $i"
done

二、列表循环 #

2.1 直接列表 #

bash
#!/bin/bash

# 直接列出元素
for color in red green blue yellow; do
    echo "颜色: $color"
done

# 使用变量
items="one two three"
for item in $items; do
    echo "项目: $item"
done

2.2 数字序列 #

bash
#!/bin/bash

# 使用 {start..end}
for i in {1..5}; do
    echo "数字: $i"
done

# 使用步长 {start..end..step}
for i in {1..10..2}; do
    echo "奇数: $i"
done

# 使用seq命令
for i in $(seq 1 5); do
    echo "数字: $i"
done

# 带步长的seq
for i in $(seq 1 2 10); do
    echo "奇数: $i"
done

2.3 文件列表 #

bash
#!/bin/bash

# 遍历当前目录的文件
for file in *.txt; do
    echo "文件: $file"
done

# 遍历所有文件
for file in *; do
    if [ -f "$file" ]; then
        echo "文件: $file"
    elif [ -d "$file" ]; then
        echo "目录: $file"
    fi
done

# 使用find命令
for file in $(find /tmp -name "*.log"); do
    echo "日志文件: $file"
done

2.4 命令输出 #

bash
#!/bin/bash

# 遍历命令输出
for user in $(cut -d: -f1 /etc/passwd); do
    echo "用户: $user"
done

# 遍历目录内容
for item in $(ls /etc); do
    echo "项目: $item"
done

# 遍历进程
for pid in $(pgrep nginx); do
    echo "nginx进程: $pid"
done

三、C风格for循环 #

3.1 基本用法 #

bash
#!/bin/bash

# 基本计数
for (( i=0; i<5; i++ )); do
    echo "计数: $i"
done

# 递减循环
for (( i=10; i>0; i-- )); do
    echo "倒计时: $i"
done

# 步长循环
for (( i=0; i<=20; i+=5 )); do
    echo "步长: $i"
done

3.2 多变量循环 #

bash
#!/bin/bash

# 同时使用多个变量
for (( i=0, j=10; i<5; i++, j-- )); do
    echo "i=$i, j=$j"
done

# 复杂条件
for (( i=0, j=0; i<5 && j<3; i++, j++ )); do
    echo "i=$i, j=$j"
done

3.3 数组索引遍历 #

bash
#!/bin/bash

arr=("apple" "banana" "cherry" "date")

# 使用索引遍历
for (( i=0; i<${#arr[@]}; i++ )); do
    echo "索引 $i: ${arr[$i]}"
done

# 同时获取索引和值
for (( i=0; i<${#arr[@]}; i++ )); do
    printf "arr[%d] = %s\n" "$i" "${arr[$i]}"
done

四、for循环高级用法 #

4.1 嵌套循环 #

bash
#!/bin/bash

# 九九乘法表
for (( i=1; i<=9; i++ )); do
    for (( j=1; j<=i; j++ )); do
        printf "%d*%d=%-4d" $j $i $((j*i))
    done
    echo ""
done

# 打印图案
for (( i=1; i<=5; i++ )); do
    for (( j=1; j<=i; j++ )); do
        printf "* "
    done
    echo ""
done

4.2 遍历关联数组 #

bash
#!/bin/bash

declare -A user
user[name]="张三"
user[age]=25
user[city]="北京"

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

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

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

4.3 读取文件行 #

bash
#!/bin/bash

# 方法一:使用cat
for line in $(cat file.txt); do
    echo "行: $line"
done

# 方法二:使用while read(推荐)
while IFS= read -r line; do
    echo "行: $line"
done < file.txt

# 方法三:读取到数组
mapfile -t lines < file.txt
for line in "${lines[@]}"; do
    echo "行: $line"
done

五、实战示例 #

5.1 批量文件处理 #

bash
#!/bin/bash

# 批量重命名
for file in *.jpg; do
    new_name="photo_$(date +%Y%m%d)_${file}"
    mv "$file" "$new_name"
    echo "重命名: $file -> $new_name"
done

# 批量转换格式
for file in *.txt; do
    new_file="${file%.txt}.md"
    cp "$file" "$new_file"
    echo "转换: $file -> $new_file"
done

# 批量压缩
for dir in */; do
    dirname=${dir%/}
    tar -czf "${dirname}.tar.gz" "$dirname"
    echo "压缩: $dirname"
done

5.2 批量用户管理 #

bash
#!/bin/bash

# 创建用户列表
users=("user1" "user2" "user3")

for user in "${users[@]}"; do
    # 检查用户是否存在
    if id "$user" &>/dev/null; then
        echo "用户 $user 已存在"
    else
        # 创建用户
        useradd -m "$user"
        echo "创建用户: $user"
        
        # 设置密码
        echo "$user:password123" | chpasswd
        echo "设置密码: $user"
    fi
done

5.3 批量服务检查 #

bash
#!/bin/bash

services=("nginx" "mysql" "redis")

for service in "${services[@]}"; do
    echo "=== 检查 $service ==="
    
    if systemctl is-active --quiet "$service"; then
        echo "状态: 运行中"
    else
        echo "状态: 未运行"
    fi
    
    if systemctl is-enabled --quiet "$service"; then
        echo "自启: 已启用"
    else
        echo "自启: 未启用"
    fi
    
    echo ""
done

5.4 并行执行任务 #

bash
#!/bin/bash

# 并行处理文件
process_file() {
    local file="$1"
    echo "处理: $file"
    sleep 1
    echo "完成: $file"
}

# 启动后台任务
for file in *.txt; do
    process_file "$file" &
done

# 等待所有任务完成
wait
echo "所有任务完成"

5.5 进度条显示 #

bash
#!/bin/bash

total=100

for (( i=0; i<=total; i++ )); do
    # 计算进度
    percent=$((i * 100 / total))
    
    # 计算进度条长度
    filled=$((i * 50 / total))
    empty=$((50 - filled))
    
    # 生成进度条
    bar=$(printf "%${filled}s" | tr ' ' '=')
    bar="${bar}$(printf "%${empty}s" | tr ' ' ' ')"
    
    # 显示进度
    printf "\r[%s] %d%%" "$bar" "$percent"
    sleep 0.1
done

echo ""
echo "完成!"

六、for循环最佳实践 #

6.1 避免常见错误 #

bash
#!/bin/bash

# 错误:文件名包含空格时
for file in $(ls); do
    echo "$file"
done

# 正确:使用glob
for file in *; do
    echo "$file"
done

# 错误:变量未加引号
files=("file one" "file two")
for file in ${files[@]}; do
    echo "$file"  # 会拆分成四个词
done

# 正确:变量加引号
for file in "${files[@]}"; do
    echo "$file"  # 正确输出两个文件名
done

6.2 性能优化 #

bash
#!/bin/bash

# 不推荐:每次循环都执行命令
for i in {1..100}; do
    result=$(some_command)
    echo "$result"
done

# 推荐:减少命令执行次数
result=$(some_command)
for i in {1..100}; do
    echo "$result"
done

# 推荐:使用内置命令
for i in {1..1000}; do
    echo "$i"  # 使用内置echo
done

# 不推荐:使用外部命令
for i in $(seq 1 1000); do
    echo "$i"
done

七、for循环速查 #

7.1 语法形式 #

形式 示例
列表循环 for i in 1 2 3; do … done
范围循环 for i in {1…10}; do … done
C风格 for ((i=0; i<10; i++)); do … done
数组遍历 for item in “${arr[@]}”; do … done
文件遍历 for f in *.txt; do … done

7.2 常用模式 #

bash
# 遍历数字
for i in {1..10}; do ... done
for ((i=1; i<=10; i++)); do ... done

# 遍历数组
for item in "${array[@]}"; do ... done
for key in "${!array[@]}"; do ... done

# 遍历文件
for file in *.txt; do ... done
for file in /path/*; do ... done

# 遍历命令输出
for line in $(command); do ... done

八、总结 #

8.1 for循环要点 #

要点 说明
列表形式 for var in list; do … done
C风格 for ((expr; expr; expr)); do … done
数组遍历 使用 “${arr[@]}”
文件遍历 使用 glob 模式
变量引用 始终使用双引号

8.2 下一步 #

你已经掌握了for循环,接下来让我们学习 while循环,了解条件循环!

最后更新:2026-03-27