bash一次将500个目录从总共160000个目录移动到子目录
出于各种原因,我需要将一个大型s3存储区移动到本地文件存储区,这些文件被存储为160000个带有子目录的目录 由于这个文件夹太多,无法使用gui FTP界面查看,因此我想将160000个根目录移动到320个目录中,每个目录中有500个目录 我是bash脚本的新手,我刚刚写了这篇文章,但我害怕我会把整个事情搞砸,不得不重做传输。我用[[“$I”-ge 3]]测试;还有一些带有子目录的目录,看起来效果不错,但我很紧张。不想重新传输所有这些数据bash一次将500个目录从总共160000个目录移动到子目录,bash,shell,amazon-s3,Bash,Shell,Amazon S3,出于各种原因,我需要将一个大型s3存储区移动到本地文件存储区,这些文件被存储为160000个带有子目录的目录 由于这个文件夹太多,无法使用gui FTP界面查看,因此我想将160000个根目录移动到320个目录中,每个目录中有500个目录 我是bash脚本的新手,我刚刚写了这篇文章,但我害怕我会把整个事情搞砸,不得不重做传输。我用[[“$I”-ge 3]]测试;还有一些带有子目录的目录,看起来效果不错,但我很紧张。不想重新传输所有这些数据 i=0; j=0; for file in *; do
i=0;
j=0;
for file in *; do
if [[ -d "$file" && ! -L "$file" ]];
then
((i++))
echo "directory $file is being written to assets_$j";
mv $file ./assets_$j/;
if [[ "$i" -ge 499 ]];
then
((j++));
((i=0));
fi
fi;
done
谢谢你的帮助 查找当前文件夹中的所有目录
- 读取文件夹的计数
- 为每个区块执行
mv
一种可能的方法是,但您无法控制计数器:
find . -type d -mindepth 1 -maxdepth 1 -print0 \
| xargs -0 -n 500 sh -c 'echo mkdir -v ./assets_$$ && echo mv -v "$@" ./assets_$$' _
这将从PID中获取资产的计数器,该PID仅在达到环绕时循环()
find
返回的顺序与glob*
()
如果要按字母顺序排序,可以添加一个简单的排序:
find . -type d -mindepth 1 -maxdepth 1 -print0 | sort -z \
| xargs -0 -n 500 sh -c 'echo mkdir -v ./assets_$$ && echo mv -v "$@" ./assets_$$' _
注意:如果您对输出感到满意,则在工作目录中尚不存在资产1、资产2等的情况下,删除回显:
dirs=(./*/)
for (( i=0,j=1; i<${#dirs[@]}; i+=500,j++ )); do
echo mkdir ./assets_$j/
echo mv "${dirs[@]:i:500}" ./assets_$j/
done
dirs=(./*/)
为了((i=0,j=1;i你的问题不是很清楚。你能举个例子说明你想要什么吗,比如说10个Directories可能很有用。如果我是你,我会创建一个包含要移动的文件夹列表的文件,然后我会遍历该文件,并在另一个文件中记录所做的工作。你可以用cp代替cpmv.如果出现问题,您可以重新启动它。在这种情况下,cp应该不会太慢(除了当您有一个好的本地副本时您可能需要rm*之外),您可能应该添加一个[[$file=assets_*]]&&continue
在循环的顶部,这样您就不会试图重命名已经存在的资产*
目录。顺便说一句,如果((i>=499))
是比较i
和499
的更好的bashism。如果您要使用不符合POSIX的语法,最好选择可读性更强的专用语法。:)我建议printf'%q'mv'${dirs[@]:i:50}/assets_$j/;echo
——它现在的做法将歪曲使用带有空格/globs/等的名称实际运行的内容(可能会在mkdir
中添加一个-p
,这样当目录已经存在时它就不会抱怨了……好吧,要么这样,要么循环递增j
,直到我们得到一个不存在的目录).@Charles你说得对,但这会让你感到困惑OP@Charles如果目录已经存在,这将造成混乱。我也不是说你错了——答案有我的赞成票;我只是在开玩笑,我就是这么做的。:)
dirs=(./*/)
for (( i=0,j=1; i<${#dirs[@]}; i+=500,j++ )); do
echo mkdir ./assets_$j/
echo mv "${dirs[@]:i:500}" ./assets_$j/
done