因为有需求所以 push AI 写的,经过多次修改后验证功能没有问题,可以适配任意文件名。直接上代码。
bash
#!/bin/bash
# 检查参数
if [ $# -eq 0 ]; then
echo "使用方法: $0 <目录路径>"
echo "示例: $0 /path/to/audio/files"
exit 1
fi
TARGET_DIR="$1"
# 检查目录是否存在
if [ ! -d "$TARGET_DIR" ]; then
echo "错误: 目录 '$TARGET_DIR' 不存在"
exit 1
fi
# 检查ffmpeg是否安装
if ! command -v ffmpeg &> /dev/null; then
echo "错误: 未找到ffmpeg命令,请先安装ffmpeg"
exit 1
fi
# 创建临时文件存储统计信息
STATS_FILE=$(mktemp)
echo "0 0 0 0" > "$STATS_FILE" # total success failed skipped
# 处理单个文件的函数
process_file() {
local wav_file="$1"
local stats_file="$2"
# 读取当前统计
read total success failed skipped < "$stats_file"
((total++))
# 提取文件名
local filename="${wav_file##*/}"
# 生成对应的flac文件名
local flac_file="${wav_file%.wav}.flac"
# 检查文件是否存在
if [ ! -f "$wav_file" ]; then
printf '[%d] 跳过: %s (文件不存在)\n' "$total" "$filename"
printf ' 完整路径: %s\n' "$wav_file"
((skipped++))
echo "$total $success $failed $skipped" > "$stats_file"
return
fi
# 检查输出文件是否已存在
if [ -f "$flac_file" ]; then
printf '[%d] 跳过: %s (FLAC已存在)\n' "$total" "$filename"
((skipped++))
echo "$total $success $failed $skipped" > "$stats_file"
return
fi
printf '[%d] 正在转换: %s\n' "$total" "$filename"
# 使用ffmpeg进行无损转换
local error_log=$(mktemp)
if ffmpeg -i "$wav_file" -c:a flac -compression_level 8 "$flac_file" -y 2>"$error_log" 1>/dev/null; then
echo " ✓ 转换成功,删除源文件"
rm -f "$wav_file"
rm -f "$error_log"
((success++))
else
echo " ✗ 转换失败,保留源文件"
# 显示有用的错误信息
local error_msg=$(grep -E "Error|error|No such|Invalid" "$error_log" | tail -1)
if [ -n "$error_msg" ]; then
echo " 错误: $error_msg"
fi
rm -f "$error_log"
((failed++))
fi
# 更新统计
echo "$total $success $failed $skipped" > "$stats_file"
}
# 导出函数和变量供 find -exec 使用
export -f process_file
export STATS_FILE
echo "开始处理目录: $TARGET_DIR"
echo "----------------------------------------"
# 使用 find -exec 处理每个文件
find "$TARGET_DIR" -type f -iname "*.wav" -exec bash -c 'process_file "$0" "$STATS_FILE"' {} \;
# 读取最终统计
read total success failed skipped < "$STATS_FILE"
echo "----------------------------------------"
echo "处理完成!"
echo "总计: $total 个文件"
echo "成功: $success 个"
echo "失败: $failed 个"
if [ $skipped -gt 0 ]; then
echo "跳过: $skipped 个"
fi
# 清理
rm -f "$STATS_FILE"