我有一个包含超过27000张图片的目录。
我想将这些文件拆分成每个包含大约500张图像的文件夹。
它们如何排序并不重要,我只想将它们分开。
答案 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(处理奇怪名称)的单独文件-r
不使用空参数列表-0
读取以null -P0
根据需要创建任意数量的流程-n 500
使用500个参数运行每个进程-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
的不同值手动调用此值,直到旧目录为空,并且您必须处理包含特殊字符的文件名。