【问题标题】:bash: devidion of large repertoire to sub-foldersbash:将大型曲目划分到子文件夹
【发布时间】:2022-06-11 22:08:43
【问题描述】:

我在共享文件夹中有 > 400.000 个文件

mol0.pdb
mol1.pdb
mol2.pdb
...
mol999.pdb
...
mol422222.pdb 

我需要将所有这些曲目分成 4 个相等的部分(按文件的数量,假设最后一部分可能比其余部分小一点)并为每个部分创建单独的文件夹(与初始文件夹添加 part_N 后缀)并将每个部分复制到其中。为此,我正在尝试实现简单的 bash 工作流程:

#!/bin/bash
home="$PWD"
project='ALL_pdb' # name of the folder with all pdb filles
#############
input="${home}"/"${project}"
output="${home}"/"${project}"_parts # name of the folder with devided files
# format of the inputs
format='pdb'
# 1- devide all filles in the input to the 4 equal parts

# 2- then iterative over the all filles and copy it to the subfolder
for lig in ${input}/*.${format}; do
lig_name=$(basename "$lig" .${format})
# mkdir $output_part_$i
# cp lig $output_part_$i
# etc
done

如何将填充物的设计自动化并将其进一步转移到单个文件夹会更好?

【问题讨论】:

  • 你所说的“相等”部分是什么意思?文件的数量(这是不可能的,因为 422222 不能被 4 整除)?已用磁盘空间? ...?
  • 完全按照填充的数量!好吧,最后一部分可能会比​​其余部分小:-)
  • 你介意最后一部分比其余部分吗?
  • 正常情况下,代码应该与位于同一文件夹中的任意数量的输入文件一起工作,并尝试将它们分成几个相等的部分。我认为最好尊重文件 ID,因此将 mol0-mol100000 放在第一个文件夹中,将 mol100000-mol200000 放在第二个文件夹中等等。在脚本的开头定义所需段的数量(单独部分)

标签: bash


【解决方案1】:

以下代码会将文件均匀地分派到编号从1<number of parts> 的目录中。较低的目录可能比较高的目录多包含 1 个文件。

#!/bin/bash
project=ALL_pdb

files=("$project"/*.pdb)
files_count=${#files[@]}

parts_count=4
parts_sizes=()

leftover=$(( files_count % parts_count ))
min_size=$(( files_count / parts_count )) 
max_size=$(( min_size + 1 ))

p=0
while (( p < leftover ));    do parts_sizes[++p]=$max_size; done
while (( p < parts_count )); do parts_sizes[++p]=$min_size; done

for (( i = 0, p = 1; parts_sizes[p]; i += parts_sizes[p++] ))
do
    d="${project}_part_$p"
    mkdir -p "$d"

    printf '%s\0' "${files[@]:i:parts_sizes[p]}" |
#   xargs -0 mv -t "$d/"       # for GNU
#   xargs -0 -J {} cp {} "$d/" # for BSD
done
说明

因为您要处理大量文件,所以您面临两个问题:

  • 为每个文件分叉一个cp 命令将会非常缓慢。
  • 对每个目标目录使用单个 cp 命令将失败并返回 Argument list too long

=> 解决这个问题需要使用xargs

现在,对于决定哪个文件将进入哪个目录,我能想到的最简单的方法是:

  1. 使用 glob 将所有文件路径加载到 bash 数组中
  2. 进行一些计算以确定每个目录的未来大小
  3. 对数组变量使用参数扩展来获取每个目标目录对应的切片。

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 2020-07-17
    • 2021-06-02
    • 2011-08-18
    • 2016-11-11
    • 1970-01-01
    • 2015-02-13
    • 2012-10-23
    • 2014-06-03
    相关资源
    最近更新 更多