在日常运维和开发中,批量处理文件与定期备份是最常见的自动化需求。编写 Shell 脚本能把这些重复劳动化繁为简,减少人为失误。下面通过实用例子说明如何构建可靠、可复用的批处理与备份脚本。
1. 批量重命名文件
假设你有一批 .jpg 照片,文件名来自相机,格式为 IMG_0001.JPG,希望全部改为统一的命名模式 photo_001.jpg(小写扩展名)。
#!/bin/bash
count=1
for file in *.JPG; do
# 检查文件是否存在(防止无匹配时的通配符展开)
[ -e "$file" ] || continue
new=$(printf "photo_%03d.jpg" $count)
mv "$file" "$new"
((count++))
done
echo "Renamed $((count-1)) files."
这里用 for 循环遍历匹配文件,结合 printf 生成固定宽度的数字序号,避免 0001 变为 1。对特殊字符安全的做法是始终给变量加双引号。
对于更复杂的改名需求,可以借助 rename 命令(Perl 版):
rename 's/IMG_(\d+)\.JPG$/photo_$1.jpg/' *.JPG
但记得先加 -n 参数预览,确认无误后再执行。
2. 批量修改文件内容
假如你需要把多个配置文件中的 DEBUG=0 改为 DEBUG=1,可以用 sed 的 -i 选项原地修改:
sed -i 's/^DEBUG=0$/DEBUG=1/' /etc/app/config*.conf
配合 find 可递归处理整个目录树中的文件:
find /path/to/project -type f -name '*.conf' \
-exec sed -i 's/old_string/new_string/g' {} \;
注意:sed -i 没有备份扩展名时直接覆盖,谨慎使用。更安全的方式是 -i.bak,操作前会自动生成备份文件(如 config.conf.bak)。
3. 文件备份脚本:保留时间戳与权限
一个最小但完整的备份脚本应具备:创建带日期的备份目录、归档文件、保留原有权限、同时删除过期备份。
#!/bin/bash
SRC="/home/user/data"
DEST="/backup"
DATE=$(date +%Y%m%d)
BACKUP_DIR="$DEST/$DATE"
# 创建当天备份目录
mkdir -p "$BACKUP_DIR" || { echo "Cannot create backup dir"; exit 1; }
# 使用 cp -a 保留所有属性(权限、时间戳等)
cp -a "$SRC"/* "$BACKUP_DIR"/
# 或者打包为压缩归档(更节省空间)
# tar -czf "$DEST/data_$DATE.tar.gz" -C /home/user data
# 清理 7 天前的备份(按备份目录名过滤)
find "$DEST" -maxdepth 1 -type d -name '20*' -mtime +7 -exec rm -rf {} \;
echo "Backup completed: $BACKUP_DIR"
cp -a会递归复制并保留符号链接、权限、时间戳,适合直接复制。- 如果数据量很大,推荐用
rsync做增量备份,仅传输变化部分,比全量复制高效得多:
rsync -av --delete "$SRC/" "$DEST/latest/"
添加 --delete 会使目标与源完全同步(删除目标中多余文件),需确认这是你想要的。
4. 确保脚本的健壮性
- 错误处理:在脚本开头加入
set -e(遇错即停)或set -u(使用未定义变量时报错),可以帮助提前发现故障。 - 路径空格:凡是涉及变量引用的地方都用双引号包裹,例如
"$file"。 - 日志记录:将输出同时写到日志文件和控制台,方便事后排查:
echo "some message" | tee -a /var/log/backup_script.log - 空变量检查:在删除或移动操作前,确保变量非空,避免类似
rm -rf "$DIR"/*但$DIR未定义导致灾难。
5. 扩展与组合
批处理和备份脚本很容易通过组合现有命令扩展为定时任务。使用 crontab -e 添加一行:
0 3 * * * /usr/local/bin/backup_script.sh >> /var/log/backup.log 2>&1
这样每天凌晨 3 点自动运行,输出记录到日志。
总之,文件批量处理与备份脚本的核心是用 for 循环和 find 遍历文件集合,以 mv、cp、sed、tar、rsync 等基础命令执行操作,并通过日期标记和过期清理机制形成稳定的自动化流程。起步时先在小范围测试,验证无误后再扩大规模,是避免事故的铁律。