Appearance
批量处理脚本
本节介绍常用的批量文件处理脚本,包括批量重命名、格式转换、数据处理和并行任务执行。
批量重命名
bash
#!/usr/bin/env bash
#
# 批量重命名脚本
# 用法:./rename.sh <目录> <原模式> <新模式>
#
set -euo pipefail
DIR="${1:-.}"
OLD_PATTERN="${2:?请提供原模式}"
NEW_PATTERN="${3:?请提供新模式}"
echo "目录:$DIR"
echo "替换:$OLD_PATTERN → $NEW_PATTERN"
echo ""
count=0
while IFS= read -r -d '' file; do
dir=$(dirname "$file")
base=$(basename "$file")
new_base="${base/$OLD_PATTERN/$NEW_PATTERN}"
if [[ "$base" != "$new_base" ]]; then
new_file="$dir/$new_base"
echo " $file → $new_file"
mv "$file" "$new_file"
(( count++ ))
fi
done < <(find "$DIR" -maxdepth 1 -type f -print0)
echo ""
echo "共重命名 $count 个文件"bash
# 使用示例
./rename.sh ./photos ".JPG" ".jpg" # 扩展名统一小写
./rename.sh ./docs "report_" "2025_report_" # 添加前缀
./rename.sh . " " "_" # 空格替换为下划线批量图片处理
bash
#!/usr/bin/env bash
#
# 批量图片压缩和转换(需要 ImageMagick)
#
set -euo pipefail
INPUT_DIR="${1:?请提供输入目录}"
OUTPUT_DIR="${2:-${INPUT_DIR}/compressed}"
QUALITY="${3:-80}"
MAX_WIDTH="${4:-1920}"
command -v convert >/dev/null 2>&1 || { echo "需要安装 ImageMagick"; exit 1; }
mkdir -p "$OUTPUT_DIR"
processed=0
failed=0
while IFS= read -r -d '' img; do
filename=$(basename "$img")
output="${OUTPUT_DIR}/${filename%.*}.jpg"
echo "处理:$img"
if convert "$img" \
-resize "${MAX_WIDTH}x${MAX_WIDTH}>" \
-quality "$QUALITY" \
-strip \
"$output" 2>/dev/null; then
orig_size=$(stat -c %s "$img")
new_size=$(stat -c %s "$output")
ratio=$(( (orig_size - new_size) * 100 / orig_size ))
echo " → $output(压缩率:${ratio}%)"
(( processed++ ))
else
echo " ❌ 失败:$img"
(( failed++ ))
fi
done < <(find "$INPUT_DIR" -maxdepth 1 \( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \) -print0)
echo ""
echo "完成:处理 $processed 张,失败 $failed 张"批量文本处理
bash
#!/usr/bin/env bash
#
# 批量替换文件中的文本内容
#
set -euo pipefail
DIR="${1:-.}"
OLD_TEXT="${2:?请提供要替换的文本}"
NEW_TEXT="${3:?请提供替换后的文本}"
FILE_PATTERN="${4:-*.txt}"
echo "目录:$DIR"
echo "替换:$OLD_TEXT → $NEW_TEXT"
echo "文件模式:$FILE_PATTERN"
echo ""
count=0
while IFS= read -r -d '' file; do
if grep -q "$OLD_TEXT" "$file" 2>/dev/null; then
# 创建备份
cp "$file" "${file}.bak"
# 执行替换
sed -i "s|${OLD_TEXT}|${NEW_TEXT}|g" "$file"
echo " 已修改:$file"
(( count++ ))
fi
done < <(find "$DIR" -name "$FILE_PATTERN" -type f -print0)
echo ""
echo "共修改 $count 个文件(原文件已备份为 .bak)"并行批量处理
bash
#!/usr/bin/env bash
#
# 并行任务处理器
# 控制并发数量,避免系统过载
#
set -euo pipefail
MAX_JOBS=4 # 最大并发数
TASK_FILE="${1:?请提供任务文件(每行一个任务)}"
# 等待任务槽位
wait_for_slot() {
while (( $(jobs -r | wc -l) >= MAX_JOBS )); do
sleep 0.5
done
}
# 处理单个任务的函数(根据实际需求修改)
process_task() {
local task="$1"
echo "处理:$task"
# 在此添加实际处理逻辑
sleep 1 # 模拟耗时操作
echo "完成:$task"
}
total=$(wc -l < "$TASK_FILE")
done_count=0
echo "总任务数:$total,并发数:$MAX_JOBS"
echo ""
while IFS= read -r task; do
[[ -z "$task" || "$task" == \#* ]] && continue # 跳过空行和注释
wait_for_slot
process_task "$task" &
(( done_count++ ))
echo "进度:${done_count}/${total}"
done < "$TASK_FILE"
# 等待所有后台任务完成
wait
echo ""
echo "所有任务处理完成!"CSV 数据批量处理
bash
#!/usr/bin/env bash
#
# 批量处理 CSV 文件
# 示例:过滤、汇总、格式转换
#
set -euo pipefail
INPUT_CSV="${1:?请提供 CSV 文件}"
OUTPUT_CSV="${2:-output.csv}"
# 去掉重复行(保留表头)
deduplicate_csv() {
local input="$1"
local output="$2"
head -1 "$input" > "$output"
tail -n +2 "$input" | sort | uniq >> "$output"
echo "去重完成:$output"
}
# 统计每列数据
summarize_csv() {
local input="$1"
local col="${2:-1}" # 默认统计第 1 列
echo "=== 第 ${col} 列统计 ==="
awk -F, -v col="$col" 'NR>1 {print $col}' "$input" | \
sort | uniq -c | sort -rn | head 20
}
# 过滤包含关键词的行
filter_csv() {
local input="$1"
local keyword="$2"
local output="$3"
head -1 "$input" > "$output"
grep -i "$keyword" "$input" | grep -v "^$(head -1 "$input")" >> "$output"
echo "过滤完成:$(wc -l < "$output") 行 → $output"
}
# 合并多个 CSV 文件(相同格式)
merge_csv() {
local output="$1"
shift
local files=("$@")
head -1 "${files[0]}" > "$output"
for f in "${files[@]}"; do
tail -n +2 "$f" >> "$output"
done
echo "合并完成:${#files[@]} 个文件 → $output($(wc -l < "$output") 行)"
}
# 示例调用
deduplicate_csv "$INPUT_CSV" "dedup_${OUTPUT_CSV}"
summarize_csv "$INPUT_CSV" 2
filter_csv "$INPUT_CSV" "active" "filtered_${OUTPUT_CSV}"批量下载
bash
#!/usr/bin/env bash
#
# 从 URL 列表批量下载文件
#
set -euo pipefail
URL_FILE="${1:?请提供 URL 列表文件}"
OUTPUT_DIR="${2:-./downloads}"
MAX_PARALLEL=3
mkdir -p "$OUTPUT_DIR"
download_file() {
local url="$1"
local filename
filename=$(basename "$url" | cut -d? -f1)
local output="${OUTPUT_DIR}/${filename}"
if [[ -f "$output" ]]; then
echo "已存在,跳过:$filename"
return 0
fi
echo "下载:$url"
if curl -fsSL -o "$output" "$url"; then
echo "完成:$filename($(du -h "$output" | cut -f1))"
else
echo "失败:$url" >&2
rm -f "$output"
fi
}
export -f download_file
export OUTPUT_DIR
# 使用 xargs 并行下载
cat "$URL_FILE" | grep -v '^#' | grep -v '^$' | \
xargs -P "$MAX_PARALLEL" -I {} bash -c 'download_file "{}"'
echo "下载完成!文件保存在:$OUTPUT_DIR"使用方法
bash
# 批量重命名
chmod +x rename.sh
./rename.sh ./photos ".JPEG" ".jpg"
# 并行处理任务(任务文件每行一个)
cat > tasks.txt << 'EOF'
task1
task2
task3
EOF
./parallel_process.sh tasks.txt
# 批量下载
cat > urls.txt << 'EOF'
https://example.com/file1.zip
https://example.com/file2.zip
EOF
./batch_download.sh urls.txt ./downloads