递归扁平文件
2024年07月02日
一、认识
多层嵌套的目录结构扁平化并删除所有多级嵌套目录 实现的效果如下:
扁平前
dir/
|-- file1.txt
|-- sub_dir1/
| |-- file2.txt
| |-- sub_sub_dir1/
| |-- file3.txt
|-- sub_dir2/
|-- file4.txt
dir2/
|-- file1.txt
|-- sub_dir1/
| |-- file2.txt
| |-- sub_sub_dir1/
| |-- file3.txt
|-- sub_dir2/
|-- file4.txt
dir3/
|-- file1.txt
|-- sub_dir1/
| |-- file2.txt
| |-- sub_sub_dir1/
| |-- file3.txt
|-- sub_dir2/
|-- file4.txt
扁平后
dir/
|-- file1.txt
|-- file2.txt
|-- file3.txt
|-- file4.txt
dir2/
|-- file1.txt
|-- file2.txt
|-- file3.txt
|-- file4.txt
di3/
|-- file1.txt
|-- file2.txt
|-- file3.txt
|-- file4.txt
二、实现
#!/bin/bash
recursive_move_files() {
local base_dir="$1"
local root_dir="$2"
local index="$3"
local has_files=false
for entry in "$base_dir"/*; do
if [ -f "$entry" ]; then
filename=$(basename "$entry")
target_move="$root_dir/$filename"
while [ -e "$target_move" ]; do
filename="${filename%.*}_${index}.${filename##*.}"
target_move="$root_dir/$filename"
((index++))
done
mv "$entry" "$target_move"
echo "Moved file '$entry' to '$target_move'"
has_files=true
elif [ -d "$entry" ]; then
recursive_move_files "$entry" "$root_dir" 0
if [ "$(ls -A "$entry")" ]; then
has_files=true
fi
rmdir "$entry" 2>/dev/null
fi
done
}
directories=$(find . -mindepth 1 -maxdepth 1 -type d)
for dir in $directories; do
root_dir=$(realpath "$dir")
echo "Processing directory: $root_dir"
recursive_move_files "$dir" "$root_dir" 0
find "$dir" -type d -empty -delete
done
echo "Done."
-
directories=$(find . -mindepth 1 -maxdepth 1 -type d)
: 获取当前目录下的所有一级子目录 -
for dir in $directories; do
: 遍历每个一级子目录并调用递归函数 -
root_dir=$(realpath "$dir")
: 转化为绝对路径 -
recursive_move_files "$dir" "$root_dir" 0
: -
find "$dir" -type d -empty -delete
: 在主循环处理完成后,使用find "$dir" -type d -empty -delete
命令来递归查找并删除空目录。通过这种方式,脚本可以更可靠地确保在所有文件移动完成后再删除空目录,避免了因为并发操作或递归调用导致的删除失败问题。 -
rmdir "$entry" 2>/dev/null
: 尝试删除空目录,忽略错误信息。在mv
和rmdir
命令执行时,添加了错误处理(2>/dev/null
)来忽略可能的错误消息,确保脚本的平稳执行。