【发布时间】:2015-07-16 12:35:41
【问题描述】:
我想以随机顺序将大量文件从一个目录移动到几个目录dst/f0..dst/f9。
我试着这样做:
ls src/*.xml | head | xargs -I {} mv {} f$(($RANDOM % 10))
但是所有文件都被移到了一个目录 src/fN
我该怎么做?谢谢
【问题讨论】:
标签: bash unix solaris-10
我想以随机顺序将大量文件从一个目录移动到几个目录dst/f0..dst/f9。
我试着这样做:
ls src/*.xml | head | xargs -I {} mv {} f$(($RANDOM % 10))
但是所有文件都被移到了一个目录 src/fN
我该怎么做?谢谢
【问题讨论】:
标签: bash unix solaris-10
按照您的编写方式,$RANDOM 只执行一次。最好生成一个每次都调用它的循环:
for file in src/*.xml
do
mv "$file" "f$((RANDOM % 10))"
done
这样您还可以避免解析ls 的输出,即a bit dangerous。
为了加快速度,您可以使用awk。如果你有 GNU awk,例如:
awk -v seed=$RANDOM 'BEGIN{srand(seed)} FNR==1{printf "mv \"%s\" dst/f%d\n", FILENAME, int(rand()*10); nextfile}' *
这使用srand(),如Random numbers generation with awk in BASH shell 和nextfile 中所述。
这将写入一个包含mv file dir/ 表达式的文件,每行一个。然后,只需执行 cat file | sh 即可。
【讨论】:
src 中有 ~160000 个文件 上面的脚本可以在 ~10 分钟内处理 ~1000 个文件 我可以加快速度吗?有可能吗?
awk 建议查看我的更新。请注意,您需要 GNU awk,我不知道它是否在您的 Solaris 10 中可用。尝试使用 /usr/xpg4/bin/awk。
date;/usr/xpg4/bin/awk -v seed=$RANDOM 'BEGIN{srand(seed)} FNR==1{printf "mv \"%s\" dst/f%d\n", FILENAME, int(rand()*10); nextfile}' *.xml > list.sh;date;cat list.sh| wc -l 上面的脚本花了 14 分钟处理约 4000 个文件 Fri Jul 17 08:42:34 YEKT 2015 ^C Fri Jul 17 08:56:49 YEKT 2015 4089 我会寻找更快的解决方案。不管怎样,谢谢你的建议!
ls -f 构建未排序的文件列表。它有效。
这是使用xargs 的另一种方式。
ls src/*.xml | xargs -i bash -c 'mv {} f$(($RANDOM % 10))'
它看起来更直接,但我会选择@fedorqui 解决方案。 xargs 将产生与输入一样多的进程
【讨论】:
这是基于@fedorqui 解决方案的最快解决方案。谢谢@fedorqui!
ls -1 -f | /usr/xpg4/bin/awk -v seed=$RANDOM 'BEGIN{srand(seed)} /\.xml$/ {printf "mv \"%s\" dst/f%d\n", $1, int(rand()*10)}' | sh
我测量了这个脚本的速度。它工作得很快
date;ls -1 -f | /usr/xpg4/bin/awk -v seed=$RANDOM 'BEGIN{srand(seed)} /\.xml$/ {printf "mv \"%s\" dst/f%d\n", $1, int(rand()*10)}' > list.sh;date;cat list.sh | wc -l
脚本的输出
Fri Jul 17 13:21:54 YEKT 2015
Fri Jul 17 13:21:54 YEKT 2015
29142
我了解解析ls 的输出可能不安全。但在这种特殊情况下,我不需要便携式解决方案
【讨论】: