我的目录中有大约 100,000 个文件。正如您可以想象的那样,这不是理想的情况,我想将目录拆分为子目录。但文件名并不能让我根据名称或其他内容将它们放入子目录中,因此我想创建 10 个目录,并在每个目录中放入大约 1000 个文件。有没有一个简单的 bash 命令或循环可以做到这一点?
答案1
尝试:
n=0; for f in *; do d="subdir$((n++ / 1000))"; mkdir -p "$d"; mv -- "$f" "$d/$f"; done
n
跟踪已移动的文件数量。在数千个批次中,每个文件都被分配到名为 的子目录subdir$((n++ / 1000))
。 (您可以根据需要调整命名。)如果尚未创建,mkdir -p "$d"
请创建该子目录。 mv -- "$f" "$d/$f"
将文件传输到该子目录。
答案2
鉴于源目录中的文件数量较多,建议的解决方案可能需要几分钟的时间。
如果您不想等待,您可能需要考虑一种不会为每次移动生成进程的解决方案。
要批量移动,您可以利用以下事实:cpio
with--pass-through
和--link
有点像移动一样 - 如果源和目标位于同一文件系统上,操作将很快,否则将创建整个副本。
与 不同的是mv
,将为每个源文件留下一个硬链接,但如果操作成功,稍后cpio -lpd
可以轻松将其全部删除:rm -r
目录分割器的实现可能类似于:
split_dir()(
local src=$1 nbatches=$2 dest=$3
local tmpd=
trap 'rm -rf "$tmpd"' EXIT
tmpd="$(mktemp -d "$tmpd")"
find -type f "$src" > "$tmpd/files"
local nfiles=$(wc -l < "$tmpd/files")
local batchsz=$((nfiles/nbatches))
( cd "$tmpd"; split -l "$batchsz" -d files )
local i
for((i=0;i<nbatches;i++)); do
mkdir -p "$dest/$i"
< x$i cpio -pdl "$dest/$i"
done
)