本文目录导读:

在Shell脚本中,有多种方式可以实现循环遍历文件,以下是常用的方法:
for循环 + 通配符(最常用)
遍历当前目录所有文件
#!/bin/bash
for file in *; do
echo "文件: $file"
done
遍历特定类型文件
#!/bin/bash
# 遍历所有txt文件
for file in *.txt; do
echo "文本文件: $file"
done
# 遍历所有log文件
for file in *.log; do
echo "日志文件: $file"
done
遍历多个目录
#!/bin/bash
# 遍历多个目录下的文件
for file in /path/to/dir1/* /path/to/dir2/*.txt; do
echo "文件路径: $file"
done
find命令 + while循环
递归遍历所有文件
#!/bin/bash
find . -type f | while read file; do
echo "找到文件: $file"
done
遍历特定类型文件并执行操作
#!/bin/bash
# 查找所有sh文件并修改权限
find . -name "*.sh" -type f | while read script; do
echo "设置执行权限: $script"
chmod +x "$script"
done
使用数组存储文件列表
#!/bin/bash
# 将文件列表存储到数组
files=(*.txt)
# 遍历数组
for file in "${files[@]}"; do
if [ -f "$file" ]; then
echo "处理文件: $file"
# 执行其他操作
fi
done
处理文件名中的特殊字符
#!/bin/bash
# 使用while IFS= read -r 处理文件名中的空格和特殊字符
find . -type f -name "*.txt" -print0 | while IFS= read -r -d '' file; do
echo "安全处理: $file"
# 使用双引号保护变量
cp "$file" "/backup/$file"
done
实用示例
批量重命名文件
#!/bin/bash
# 将所有的.jpg文件重命名为_old.jpg
for file in *.jpg; do
if [ -f "$file" ]; then
mv "$file" "${file%.jpg}_old.jpg"
echo "重命名: $file -> ${file%.jpg}_old.jpg"
fi
done
统计文件行数
#!/bin/bash
total_lines=0
for file in *.txt; do
if [ -f "$file" ]; then
lines=$(wc -l < "$file")
echo "$file: $lines 行"
total_lines=$((total_lines + lines))
fi
done
echo "总行数: $total_lines"
处理子目录中的文件
#!/bin/bash
# 递归处理所有子目录中的.log文件
find . -type f -name "*.log" | while read logfile; do
dir=$(dirname "$logfile")
filename=$(basename "$logfile")
echo "目录: $dir, 文件: $filename"
# 检查文件大小
size=$(stat -f%z "$logfile" 2>/dev/null || stat -c%s "$logfile" 2>/dev/null)
if [ "$size" -gt 1048576 ]; then # 大于1MB
echo " 文件大于1MB: $size bytes"
fi
done
注意事项
- 文件名包含空格:始终使用双引号包裹变量
"$file" - 空目录处理:使用
shopt -s nullglob防止通配符不匹配时返回字符串本身 - 递归遍历:使用
find命令,而不是ls -R解析输出
#!/bin/bash
# 处理空目录的情况
shopt -s nullglob
for file in *.txt; do
echo "处理: $file"
done
shopt -u nullglob
进阶:使用while循环处理多列数据
#!/bin/bash
# 处理包含多列信息的文件列表
while IFS= read -r line; do
# 假设文件列表包含:文件名 大小 修改日期
filename=$(echo "$line" | awk '{print $1}')
size=$(echo "$line" | awk '{print $2}')
date=$(echo "$line" | awk '{print $3}')
echo "文件: $filename, 大小: $size, 日期: $date"
done < file_list.txt
选择哪种方法取决于你的具体需求:
- 简单遍历:使用
for循环 + 通配符 - 递归遍历:使用
find命令 - 处理特殊字符:使用
while IFS= read -r