如何将目录的所有文件移动到具有给定数量文件的多个目录中?

时间:2012-01-31 15:42:23

标签: bash shell

我有一个包含超过27000张图片的目录。

我想将这些文件拆分成每个包含大约500张图像的文件夹。

它们如何排序并不重要,我只想将它们分开。

4 个答案:

答案 0 :(得分:9)

“简单”查找/ xargs会这样做:

find -maxdepth 1 -type f -print0 | xargs -r -0 -P0 -n 500 sh -c 'mkdir newdir.$$; mv "$@" newdir.$$/' xx

说明:

  • 找到
    • -maxdepth 1阻止查找以递归方式遍历任何目录,安全,如果您知道自己没有目录则不需要
    • -type f仅查找文件
    • -print0使用null char而不是LF(处理奇怪名称)的单独文件
  • xargs的
    • -r不使用空参数列表
    • 运行
    • -0读取以null
    • 分隔的文件
    • -P0根据需要创建任意数量的流程
    • -n 500使用500个参数运行每个进程
  • SH
    • -c运行命令行脚本作为下一个参数提供
    • mkdir newdir.$$创建一个以shell进程PID
    • 结尾的新目录
    • mv "$@" newdir.$$/将脚本的参数(每个引用它们)移动到新创建的目录
    • 命令行提供脚本的
    • xx名称(参见sh manual)

请注意,这是我将在制作中使用的内容,它主要基于$$(pid)对于xargs执行的每个进程都不同的事实

如果您需要排序的文件,您可以在查找xargs之间建立sort -z

如果您想要更有意义的目录名,可以使用以下内容:

echo 1 >../seq
find -maxdepth 1 -type f -print0 |sort -z | xargs -r -0 -P1 -n 500 sh -c 'read NR <../seq; mkdir newdir.$NR; mv "$@" newdir.$NR/; expr $NR + 1 >../seq' xx
  • echo 1 > ../seq将第一个目录后缀写入文件中(确保它不在当前目录中)
  • -P1告诉xargs一次运行一个命令以防止竞争条件
  • read NR <../seq从文件
  • 中读取当前目录后缀
  • expr $NR + 1 >../seq为下次运行编写下一个目录后缀
  • sort -z对文件进行排序

答案 1 :(得分:6)

以下内容应该有效:

dest_base="destination"
src_dir="src/"

filesperdir=500
atfile=0
atdir=0
for file in $src_dir/*; do
    if ((atfile == 0)); then
        dest_dir=$(printf "$dest_base/%0.5d" $atdir)
        [[ -d $dest_dir ]] || mkdir -p $dest_dir
    fi
    mv $file $dest_dir
    ((atfile++))
    if ((atfile >= filesperdir)); then
        atfile=0
        ((atdir++))
    fi
done

答案 2 :(得分:0)

好的,以下解决方案存储包含500个文件名列表的临时文件。根据需要调整它。 首先,我们列出当前目录中的所有文件,将500分割为500,并将结果存储在outputXYZ。*文件中

ls | split -l 500 - outputXYZ.
# Then we go through all those files
count=0
for i in outputXYZ.*; do 
    ((count++))
    # We store the result in dir.X directory (created in current directory)
    mkdir dir.$count 2>/dev/null

    # And move those files into it 
    cat $i | xargs mv -t dir.$count

    # remove the temp file
    rm $i
done

最后,你的所有图像都在目录dir.1(1..500),dir.2(501..1000),dir.3等中。

答案 3 :(得分:-1)

你可以从这开始:

mkdir new_dir ; find source_dir | head -n 500  | xargs -I {} mv {} new_dir 

这将创建new_dir并将500个文件从old_dir移至new_dir。您仍然必须为new_dir的不同值手动调用此值,直到旧目录为空,并且您必须处理包含特殊字符的文件名。