教程:使用Shell脚本实现文件重命名与分类整理
在日常文件管理中,我们经常需要对文件进行重命名、整理分类,以及统一文件扩展名的大小写。这里将介绍三个Shell脚本,分别实现这些功能,让文件管理变得更加高效和有序。
脚本一:重命名文件与统一文件扩展名为小写
作用:
- 重命名文件:按顺序重命名文件为数字.扩展名的格式,例如 1.jpg, 2.txt 等。
- 统一文件扩展名为小写:将所有文件的扩展名转换为小写字母。
使用方法:
-
进入目标目录:
cd 目标目录路径
-
创建脚本文件:
vim uniform-file-names.sh
将脚本内容粘贴进去,并保存退出。
-
运行脚本:
bash uniform-file-names.sh
脚本内容:
#!/bin/bash
# 初始化计数器
count=1
# 第一步:重命名文件
for file in *.*; do
# 获取文件的扩展名
extension="${file##*.}"
# 重命名文件,格式为数字.扩展名
mv -- "$file" "${count}.${extension}"
# 计数器递增
((count++))
done
# 第二步:统一文件扩展名为小写
for file in *.*; do
# 获取文件名和扩展名
filename="${file%.*}"
extension="${file##*.}"
# 转换扩展名为小写
new_extension="${extension,,}"
# 如果新旧扩展名不同,则重命名文件
if [[ "$extension" != "$new_extension" ]]; then
mv -- "$file" "${filename}.${new_extension}"
fi
done
# 输出完成信息
echo "文件重命名和扩展名转换完成。"
脚本二:整理文件和清理空文件夹
作用:
- 移动文件:使用
find
命令获取文件列表,并将文件移动到当前目录。 - 处理重名文件:自动添加数字后缀以区分重名文件。
- 显示进度条:实现简单的进度条显示文件移动进度。
- 删除空文件夹:递归查找并删除所有空文件夹。
使用方法:
-
进入目标目录:
cd 目标目录路径
-
创建脚本文件:
vim organize-files.sh
将脚本内容粘贴进去,并保存退出。
-
运行脚本:
bash organize-files.sh
脚本内容:
#!/bin/bash
# 获取当前目录下的所有文件(包括子目录)
mapfile -t files < <(find . -type f)
# 获取文件总数
total_files=${#files[@]}
# 初始化进度条
echo -n '['
progress=0
bar_length=50
# 移动文件到当前目录并显示进度条
echo "Moving files to current directory..."
for ((i = 0; i < $total_files; i++)); do
filename="${files[$i]}"
# 打印进度条
progress=$(( (i * 100) / total_files ))
num_bar=$(( (progress * bar_length) / 100 ))
num_space=$(( bar_length - num_bar ))
bar=$(printf "%${num_bar}s" | tr ' ' '=')
space=$(printf "%${num_space}s" | tr ' ' ' ')
echo -ne "\r[${bar}${space}] ($progress%)"
# 获取文件名和目标路径
base_filename=$(basename "$filename")
target_path="./$base_filename"
# 检查目标路径是否存在重复文件名
if [[ -e "$target_path" ]]; then
# 文件名已存在,添加数字后缀
suffix=1
while [[ -e "$target_path" ]]; do
target_path="./${base_filename%.*}_${suffix}.${base_filename##*.}"
((suffix++))
done
fi
# 移动文件到当前目录
mv "$filename" "$target_path"
done
# 完成进度条
echo -e "\nMove operation completed."
# 递归删除所有空文件夹
echo "递归删除所有空文件夹..."
find . -mindepth 1 -type d -
empty -exec rmdir {} \;
echo "所有空文件夹已删除."
exit 0
脚本三:文件分类与批量命名
作用:
- 文件分类:根据文件类型将文件移动到相应文件夹。
- 批量命名:对特定类型的文件进行统一命名操作,并记录操作日志。
使用方法:
-
进入目标目录:
cd 目标目录路径
-
创建脚本文件:
vim classify-and-rename.sh
将脚本内容粘贴进去,并保存退出。
-
运行脚本:
bash classify-and-rename.sh
脚本内容:
#!/bin/bash
# 创建日志文件夹和日志文件
mkdir -p log
log_file="log/$(date '+%Y-%m-%d_%H-%M-%S').log"
touch "$log_file" # 确保日志文件存在
# 启用nocasematch选项,使得比较时忽略大小写
shopt -s nocasematch
# 定义文件类型和对应的扩展名
declare -A FILE_TYPES=(
["视频"]="mp4 mkv avi mov wmv flv webm mpg mpeg"
["图片"]="jpg jpeg png gif bmp tiff svg ico webp"
["文本"]="txt md pdf doc docx xls xlsx ppt pptx odt ods odp rtf html csv epub"
["音频"]="mp3 wav aac flac ogg m4a"
["压缩"]="zip rar tar gz bz2 7z"
["其他"]="*"
)
# 检查并创建存在的文件类型的文件夹
for folder in "${!FILE_TYPES[@]}"; do
found=false
for ext in ${FILE_TYPES[$folder]}; do
if ls *.$ext 1> /dev/null 2>&1; then
found=true
break
fi
done
if [ "$found" = true ]; then
mkdir -p "$folder"
fi
done
# 分类和重命名文件
find . -maxdepth 1 -type f | while read file; do
safe_file=$(basename "$file")
matched=false
for category in "${!FILE_TYPES[@]}"; do
for ext in ${FILE_TYPES[$category]}; do
if [[ "${safe_file##*.}" == "$ext" ]]; then
new_file="$category/$safe_file"
count=1
while [[ -e "$new_file" ]]; do
base="${safe_file%.*}"
new_file="$category/${base}_$count.$ext"
((count++))
done
mv -- "$file" "$new_file"
echo "Moved $file to $new_file" >> "$log_file"
matched=true
break 2
fi
done
done
# 如果文件没有匹配到任何类型,移动到“其他”文件夹
if [[ "$matched" == false ]]; then
mv -- "$file" "其他/"
echo "Moved $file to '其他/'" >> "$log_file"
fi
done
# 分类和重命名完成后询问用户是否继续重命名
while true; do
read -p "分类移动完成后,是否继续重命名文件?(y/n): " rename_choice
if [[ $rename_choice == 'y' ]]; then
echo "当前的分类有:"
declare -i index=1
declare -A valid_types
for key in "${!FILE_TYPES[@]}"; do
if [ -d "$key" ] && [ "$(ls -A $key)" ]; then
echo "$index.$key"
valid_types[$index]=$key
let index++
fi
done
read -p "请选择您想要重命名的文件类型编号: " type_index
type_choice=${valid_types[$type_index]}
read -p "请输入新的统一文件名: " new_name
extensions=${FILE_TYPES[$type_choice]}
count=1
for ext in $extensions; do
for file in "$type_choice"/*.$ext; do
if [[ -f "$file" ]]; then
lower_ext="${ext,,}"
new_file="$type_choice/${new_name}_${count}.$lower_ext"
mv -- "$file" "$new_file"
echo "Renamed $file to $new_file" >> "$log_file"
((count++))
fi
done
done
echo "所有的$type_choice文件已重命名为$new_name。"
else
break
fi
done
echo "所有操作已完成。详细信息请查看日志文件:$log_file"
结语
注意文件备份,这几个脚本可以放到usr/bin
目录,这样就可以在整个Linux中任何目录使用。同时在安卓手机可以使用Termux
App创建脚本来整理手机文件。同时这几个脚本需要配合使用,因为有文件名称带-
_
这些特殊符号分类脚本无法处理。
我暂时没办法合并这三个脚本,如果有朋友可以有能力合并的话请一定与我分享,万分感谢!!