batch_rename_menu
批量文件重命名脚本,支持添加前后缀、替换字符、序号重命名、大小写转换、去空格等一键批量操作。
一键脚本
bash <(curl -sL gitee.com/meimolihan/linux-command_sh/raw/master/batch_rename_menu.sh)
效果预览
脚本源码
#!/bin/bash
set -uo pipefail
gl_hui='\033[38;5;59m'
gl_hong='\033[38;5;9m'
gl_lv='\033[38;5;10m'
gl_huang='\033[38;5;11m'
gl_lan='\033[38;5;32m'
gl_bai='\033[38;5;15m'
gl_zi='\033[38;5;13m'
gl_bufan='\033[38;5;14m'
log_info() { echo -e "${gl_lan}[信息]${gl_bai} $*"; }
log_ok() { echo -e "${gl_lv}[成功]${gl_bai} $*"; }
log_warn() { echo -e "${gl_huang}[警告]${gl_bai} $*"; }
log_error() { echo -e "${gl_hong}[错误]${gl_bai} $*" >&2; }
break_end() {
echo -e "${gl_lv}操作完成${gl_bai}"
echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
read -r -n 1 -s -p ""
echo ""
clear
}
sleep_fractional() {
local seconds=$1
if sleep "$seconds" 2>/dev/null; then return 0; fi
if command -v perl >/dev/null 2>&1; then perl -e "select(undef, undef, undef, $seconds)"; return 0; fi
if command -v python3 >/dev/null 2>&1; then python3 -c "import time; time.sleep($seconds)"; return 0; fi
if command -v python >/dev/null 2>&1; then python -c "import time; time.sleep($seconds)"; return 0; fi
local int_seconds=$(echo "$seconds" | awk '{print int($1+0.999)}')
sleep "$int_seconds"
}
cancel_return() {
local menu_name="${1:-退出脚本}"
echo -ne "${gl_lv}即将 ${gl_huang}${menu_name}${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.5
echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.6
echo ""
clear
}
exit_script() {
echo ""
echo -ne "${gl_hong}感谢使用,再见!${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.5
echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.6
clear
exit 0
}
handle_y_n() {
echo -ne "\r${gl_hong}无效的选择,请输入 ${gl_bai}(${gl_lv}y${gl_bai}或${gl_hong}N${gl_bai})${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.3
echo -ne "\r${gl_huang}无效的选择,请输入 ${gl_bai}(${gl_lv}y${gl_bai}或${gl_hong}N${gl_bai})${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.3
echo -ne "\r${gl_lv}无效的选择,请输入 ${gl_bai}(${gl_lv}y${gl_bai}或${gl_hong}N${gl_bai})${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.6
echo ""
return 2
}
exit_animation() {
echo -ne "\r${gl_lv}即将退出 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.5
echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.6
echo ""
clear
}
cancel_empty() {
local menu_name="${1:-上一级选单}"
echo -e "${gl_hong}空输入,返回 ${gl_huang}${menu_name}${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.5
echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.6
echo ""
clear
}
handle_invalid_input() {
echo -ne "\r${gl_hong}无效的输入,请重新输入 ${gl_zi} 2 ${gl_hong}秒后返回 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.3
echo -ne "\r${gl_huang}无效的输入,请重新输入 ${gl_zi} 1 ${gl_huang}秒后返回 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.3
echo -e "\r${gl_lv}无效的输入,请重新输入 ${gl_zi} 0 ${gl_lv}秒后返回 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep_fractional 0.6
continue
}
go_parent_directory() {
if [[ "$(pwd)" != "/" ]]; then
local current_path="$(pwd)"
cd ..
echo -ne "${gl_lv}已返回上级目录: ${gl_huang}$(pwd) ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
exit_animation
else
echo -ne "${gl_huang}已经在根目录: ${gl_hong}/ ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
exit_animation
fi
}
batch_rename_files() {
while true; do
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
clear
echo -e ""
echo -e "${gl_zi}>>> 批量重命名文件${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
else
echo -e "${gl_bai}当前目录: ${gl_lv}${current_dir}${gl_bai} ${gl_bai}文件数量: ${gl_lv}${file_count}${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
if [[ $file_count -le 20 ]]; then
echo -e "${gl_bai}文件列表:${gl_bai}"
for i in "${!files[@]}"; do
local file="${files[$i]}"
local filename=$(basename "$file")
echo -e " ${gl_huang}$((i + 1))${gl_bai}. ${gl_bufan}${filename}${gl_bai}"
done
else
echo -e "${gl_bai}显示前 20 个文件:${gl_bai}"
for i in {0..19}; do
if [[ $i -lt $file_count ]]; then
local file="${files[$i]}"
local filename=$(basename "$file")
echo -e " ${gl_huang}$((i + 1))${gl_bai}. ${gl_bufan}${filename}${gl_bai}"
fi
done
echo -e " ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}还有 $((file_count - 20)) 个文件${gl_bai}"
fi
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bufan}1. ${gl_bai}添加前缀 ${gl_bufan}2. ${gl_bai}添加后缀"
echo -e "${gl_bufan}3. ${gl_bai}替换字符串 ${gl_bufan}4. ${gl_bai}序号重命名"
echo -e "${gl_bufan}5. ${gl_bai}大小写转换 ${gl_bufan}6. ${gl_bai}移除字符"
echo -e "${gl_bufan}7. ${gl_bai}删除所有空格"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_hong}0. ${gl_bai}退出脚本"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
read -r -e -p "$(echo -e "${gl_bai}请选择重命名模式: ")" rename_mode
case "$rename_mode" in
1) rename_files_add_prefix ;;
2) rename_files_add_suffix ;;
3) rename_files_replace_string ;;
4) rename_files_sequential ;;
5) rename_files_change_case ;;
6) rename_files_remove_chars ;;
7) rename_files_remove_spaces ;;
0) exit_script ;;
*) handle_invalid_input ;;
esac
done
}
rename_files_add_prefix() {
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
exit_animation
return
fi
echo -e ""
echo -e "${gl_zi}>>> 批量添加前缀${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
read -e -p "$(echo -e "${gl_bai}请输入要添加的前缀(${gl_huang}0${gl_bai}返回): ")" prefix
if [[ -z "$prefix" ]]; then
log_warn "前缀不能为空"
exit_animation
return
fi
[ "$prefix" == "0" ] && { cancel_return "上一级选单"; return 1; }
echo -e "${gl_bai}预览重命名结果:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local rename_count=0
local rename_files=()
for file in "${files[@]}"; do
local filename=$(basename "$file")
local dir=$(dirname "$file")
local newname="${dir}/${prefix}${filename}"
if [[ "$filename" != "${prefix}${filename}" ]]; then
rename_files+=("$file:$newname")
echo -e " ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}${prefix}${filename}${gl_bai}"
fi
done
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"
if [[ ${#rename_files[@]} -gt 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
[ "$confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }
case "$confirm" in
[Yy])
for rename_pair in "${rename_files[@]}"; do
IFS=':' read -r old_name new_name <<<"$rename_pair"
if mv "$old_name" "$new_name" 2>/dev/null; then
((rename_count++))
log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
else
log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
fi
done
;;
[Nn])
log_warn "操作已取消"
;;
*) handle_y_n ;;
esac
else
log_warn "没有文件需要重命名(可能文件已有相同前缀)"
fi
if [[ $rename_count -gt 0 ]]; then
log_ok "成功重命名 ${rename_count} 个文件"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
break_end
}
rename_files_add_suffix() {
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
exit_animation
return
fi
echo -e ""
echo -e "${gl_zi}>>> 批量添加后缀${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
read -e -p "$(echo -e "${gl_bai}请输入要添加的后缀 (不含扩展名)(${gl_huang}0${gl_bai}返回): ")" suffix
if [[ -z "$suffix" ]]; then
log_warn "后缀不能为空"
exit_animation
return
fi
[[ "$suffix" == "0" ]] && { cancel_return "上一级选单"; return 1; }
echo -e "${gl_bai}预览重命名结果:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local rename_count=0
local rename_files=()
for file in "${files[@]}"; do
local filename=$(basename "$file")
local dir=$(dirname "$file")
local newname
if [[ "$filename" =~ \. ]]; then
local ext="${filename##*.}"
local name="${filename%.*}"
if [[ "$name" == "$ext" ]]; then
newname="${dir}/${filename}${suffix}"
else
newname="${dir}/${name}${suffix}.${ext}"
fi
else
newname="${dir}/${filename}${suffix}"
fi
if [[ "$filename" != "$(basename "$newname")" ]]; then
rename_files+=("$file:$newname")
echo -e " ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
fi
done
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"
if [[ ${#rename_files[@]} -gt 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
case "$confirm" in
[Yy])
for rename_pair in "${rename_files[@]}"; do
IFS=':' read -r old_name new_name <<<"$rename_pair"
if mv "$old_name" "$new_name" 2>/dev/null; then
((rename_count++))
log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
else
log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
fi
done
;;
[Nn])
log_warn "操作已取消"
;;
*) handle_y_n ;;
esac
else
log_warn "没有文件需要重命名"
fi
if [[ $rename_count -gt 0 ]]; then
log_ok "成功重命名 ${rename_count} 个文件"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
break_end
}
rename_files_replace_string() {
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
exit_animation
return
fi
echo -e ""
echo -e "${gl_zi}>>> 替换字符${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
read -e -p "$(echo -e "${gl_bai}请输入要替换的字符串(${gl_huang}0${gl_bai}返回): ")" old_str
[[ "$old_str" == "0" ]] && { cancel_return "上一级选单"; return 1; }
if [[ -z "$old_str" ]]; then
log_warn "要替换的字符串不能为空"
exit_animation
return
fi
read -r -e -p "$(echo -e "${gl_bai}请输入替换为的字符串: ")" new_str
[ "$new_str" == "0" ] && { cancel_return "上一级选单"; return 1; }
echo -e "${gl_bai}预览重命名结果:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local rename_count=0
local rename_files=()
for file in "${files[@]}"; do
local filename=$(basename "$file")
local dir=$(dirname "$file")
local newname="${dir}/${filename//$old_str/$new_str}"
if [[ "$filename" != "$(basename "$newname")" ]]; then
rename_files+=("$file:$newname")
echo -e " ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
fi
done
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"
if [[ ${#rename_files[@]} -gt 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
[ "$confirm" == "0" ] && { cancel_return "上一级选单"; return 1; }
case "$confirm" in
[Yy])
for rename_pair in "${rename_files[@]}"; do
IFS=':' read -r old_name new_name <<<"$rename_pair"
if mv "$old_name" "$new_name" 2>/dev/null; then
((rename_count++))
log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
else
log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
fi
done
;;
[Nn])
log_warn "操作已取消"
;;
*) handle_y_n ;;
esac
else
log_warn "没有找到匹配的字符串 '$old_str'"
fi
if [[ $rename_count -gt 0 ]]; then
log_ok "成功重命名 ${rename_count} 个文件"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
break_end
}
rename_files_sequential() {
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
exit_animation
return
fi
echo -e ""
echo -e "${gl_huang}>>> 序号重命名模板说明:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e " ${gl_huang}###${gl_bai} 表示三位数字序号 (如: 001, 002)"
echo -e " ${gl_huang}##${gl_bai} 表示两位数字序号 (如: 01, 02)"
echo -e " ${gl_huang}#${gl_bai} 表示一位数字序号 (如: 1, 2)"
echo -e " ${gl_huang}%d${gl_bai} 表示数字序号 (如: 1, 2, 3)"
echo -e ""
echo -e "${gl_bai}示例:${gl_bai}"
echo -e " ${gl_huang}image-###.jpg${gl_bai} -> ${gl_lv}image-001.jpg, image-002.jpg, ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
echo -e " ${gl_huang}document_##.txt${gl_bai} -> ${gl_lv}document_01.txt, document_02.txt, ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
echo -e " ${gl_huang}file_#.pdf${gl_bai} -> ${gl_lv}file_1.pdf, file_2.pdf, ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e ""
echo -e "${gl_zi}>>> 序号重命名${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
read -e -p "$(echo -e "${gl_bai}请输入文件名模板(${gl_huang}0${gl_bai}返回): ")" template
[[ "$template" == "0" ]] && { cancel_return "上一级选单"; return 1; }
if [[ -z "$template" ]]; then
log_warn "模板不能为空"
exit_animation
return
fi
echo -e "${gl_bai}预览重命名结果:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local rename_count=0
local rename_files=()
local idx=1
for file in "${files[@]}"; do
local dir=$(dirname "$file")
local filename=$(basename "$file")
local ext="${filename##*.}"
local name_without_ext="${filename%.*}"
if [[ "$filename" =~ \. ]] && [[ "$name_without_ext" != "$ext" ]]; then
local newname_template="${template%.*}"
if [[ -z "$newname_template" ]]; then
newname_template="$template"
fi
if [[ "$newname_template" =~ "###" ]]; then
newname_template="${newname_template//###/$(printf "%03d" $idx)}"
elif [[ "$newname_template" =~ "##" ]]; then
newname_template="${newname_template//##/$(printf "%02d" $idx)}"
elif [[ "$newname_template" =~ "#" ]]; then
newname_template="${newname_template//#/$idx}"
elif [[ "$newname_template" =~ "%d" ]]; then
newname_template="${newname_template//%d/$idx}"
else
newname_template="${newname_template}_${idx}"
fi
local newname="${dir}/${newname_template}.${ext}"
else
local newname_template="$template"
if [[ "$newname_template" =~ "###" ]]; then
newname_template="${newname_template//###/$(printf "%03d" $idx)}"
elif [[ "$newname_template" =~ "##" ]]; then
newname_template="${newname_template//##/$(printf "%02d" $idx)}"
elif [[ "$newname_template" =~ "#" ]]; then
newname_template="${newname_template//#/$idx}"
elif [[ "$newname_template" =~ "%d" ]]; then
newname_template="${newname_template//%d/$idx}"
else
newname_template="${newname_template}_${idx}"
fi
local newname="${dir}/${newname_template}"
fi
rename_files+=("$file:$newname")
echo -e " ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
((idx++))
done
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"
if [[ ${#rename_files[@]} -gt 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
[ "$confirm" == "0" ] && { cancel_return "上一级选单"; return 1; }
case "$confirm" in
[Yy])
for rename_pair in "${rename_files[@]}"; do
IFS=':' read -r old_name new_name <<<"$rename_pair"
if mv "$old_name" "$new_name" 2>/dev/null; then
((rename_count++))
log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
else
log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
fi
done
;;
[Nn])
log_warn "操作已取消"
;;
*) handle_y_n ;;
esac
fi
if [[ $rename_count -gt 0 ]]; then
log_ok "成功重命名 ${rename_count} 个文件"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
break_end
}
rename_files_change_case() {
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
exit_animation
return
fi
while true; do
echo -e ""
echo -e "${gl_zi}>>> 大小写转换${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bufan}1. ${gl_bai}转为小写 ${gl_bufan}2. ${gl_bai}转为大写"
echo -e "${gl_bufan}3. ${gl_bai}首字母大写 ${gl_bufan}4. ${gl_bai}单词首字母大写"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_huang}0. ${gl_bai}返回上一级选单"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
read -r -e -p "$(echo -e "${gl_bai}请选择转换模式: ")" case_mode
case "$case_mode" in
0) cancel_return; return ;;
1 | 2 | 3 | 4)
local rename_count=0
local rename_files=()
echo -e "${gl_bai}预览重命名结果:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
for file in "${files[@]}"; do
local filename=$(basename "$file")
local dir=$(dirname "$file")
local newname
case "$case_mode" in
1) newname="${dir}/${filename,,}" ;;
2) newname="${dir}/${filename^^}" ;;
3) newname="${dir}/${filename^}" ;;
4)
newname="$filename"
if [[ "$newname" =~ [a-zA-Z] ]]; then
newname=$(echo "$newname" | sed -E 's/(^|_)([a-z])/\1\u\2/g' 2>/dev/null || echo "$newname")
fi
newname="${dir}/${newname}"
;;
esac
if [[ "$filename" != "$(basename "$newname")" ]]; then
rename_files+=("$file:$newname")
echo -e " ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
fi
done
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"
if [[ ${#rename_files[@]} -gt 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
[ "$confirm" = "0" ] && { cancel_return "上一级选单"; continue; }
case "$confirm" in
[Yy])
for rename_pair in "${rename_files[@]}"; do
IFS=':' read -r old_name new_name <<<"$rename_pair"
if mv "$old_name" "$new_name" 2>/dev/null; then
((rename_count++))
log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
else
log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
fi
done
;;
[Nn])
log_warn "操作已取消"
;;
*) handle_y_n ;;
esac
else
log_warn "没有文件需要转换大小写"
fi
if [[ $rename_count -gt 0 ]]; then
log_ok "成功重命名 ${rename_count} 个文件"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
break_end
return
;;
*) handle_invalid_input ;;
esac
done
}
rename_files_remove_chars() {
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
exit_animation
return
fi
echo -e ""
echo -e "${gl_zi}>>> 移除字符${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
read -e -p "$(echo -e "${gl_bai}请输入要移除的字符或模式(${gl_huang}0${gl_bai}返回): ")" remove_pattern
[[ "$remove_pattern" == "0" ]] && { cancel_return "上一级选单"; return 1; }
if [[ -z "$remove_pattern" ]]; then
log_warn "要移除的字符不能为空"
exit_animation
return
fi
echo -e "${gl_bai}预览重命名结果:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local rename_count=0
local rename_files=()
for file in "${files[@]}"; do
local filename=$(basename "$file")
local dir=$(dirname "$file")
local newname="${dir}/${filename//$remove_pattern/}"
if [[ "$filename" != "$(basename "$newname")" ]]; then
rename_files+=("$file:$newname")
echo -e " ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
fi
done
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"
if [[ ${#rename_files[@]} -gt 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
[[ "$confirm" == "0" ]] && { cancel_return "上一级选单"; return 1; }
case "$confirm" in
[Yy])
for rename_pair in "${rename_files[@]}"; do
IFS=':' read -r old_name new_name <<<"$rename_pair"
if mv "$old_name" "$new_name" 2>/dev/null; then
((rename_count++))
log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
else
log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
fi
done
;;
[Nn])
log_warn "操作已取消"
;;
*) handle_y_n ;;
esac
else
log_warn "没有找到匹配的字符 '$remove_pattern'"
fi
if [[ $rename_count -gt 0 ]]; then
log_ok "成功重命名 ${rename_count} 个文件"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
break_end
}
rename_files_remove_spaces() {
local current_dir=$(pwd)
local files=()
while IFS= read -r -d $'\0' file; do
if [[ -f "$file" ]]; then
files+=("$file")
fi
done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
local file_count=${#files[@]}
if [[ $file_count -eq 0 ]]; then
echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
exit_animation
return
fi
echo -e ""
echo -e "${gl_zi}>>> 删除文件名中的所有空格${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}注意: 此操作将删除文件名中的所有空格字符${gl_bai}"
echo -e "${gl_bai}包括文件名开头、中间和结尾的空格${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}预览重命名结果:${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local rename_count=0
local rename_files=()
for file in "${files[@]}"; do
local filename=$(basename "$file")
local dir=$(dirname "$file")
local newname="${dir}/${filename// /}"
if [[ "$filename" != "$(basename "$newname")" ]]; then
rename_files+=("$file:$newname")
echo -e " ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
fi
done
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"
if [[ ${#rename_files[@]} -gt 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
[[ "$confirm" == "0" ]] && { cancel_return "上一级选单"; return 1; }
case "$confirm" in
[Yy])
for rename_pair in "${rename_files[@]}"; do
IFS=':' read -r old_name new_name <<<"$rename_pair"
if mv "$old_name" "$new_name" 2>/dev/null; then
((rename_count++))
log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
else
log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
fi
done
;;
[Nn])
log_warn "操作已取消"
;;
*) handle_y_n ;;
esac
else
log_warn "没有文件名包含空格"
fi
if [[ $rename_count -gt 0 ]]; then
log_ok "成功重命名 ${rename_count} 个文件"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
break_end
}
batch_rename_files
创建本地脚本
new_script="new_test.sh"
cat > "$new_script" << 'EOF'
#!/bin/bash
# 粘贴脚本源码
EOF
# 保留本地脚本,去掉 rm -f "$new_script"
chmod +x "$new_script" && ./"$new_script" && rm -f "$new_script"