如何按计数将文件移动到子目录中?

如何按计数将文件移动到子目录中?

我的目录中有大约 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

鉴于源目录中的文件数量较多,建议的解决方案可能需要几分钟的时间。

如果您不想等待,您可能需要考虑一种不会为每次移动生成进程的解决方案。

要批量移动,您可以利用以下事实:cpiowith--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
)

相关内容