1)我有从0到3120203的目录(注意目录不是按顺序排列的,它们是随机的)
-bash-4.1$ ls
0 1261826 211205 2398339 267475 295482 339902 395546 457254 503959 538784 583032 643106 78093 906653
1000791 126359 211250 2398362 267592 295488 340070 39565 457378 504052 538846 583103 643168 78143 91594
1001022 126944 2114355 2398373 267667 29583 341088 395652 457471 504160 540470 583316 64447 781579 91777
1002557 127163 2129010 2398380 267771 2959608 341300 395786 457628 504219 540632 583875 645373 782220 921760
1004183 127316 2129165 2398388 268076 296331 341452 396207 457758 504278 541300 583998 645437 78227 924976
1004399 127416 2132965 2398396 2681923 296456 341512 39720 457820 504337 541754 584219 645816 782272 925382
1005369 130416 2137199 2398482 268333 2964801 341688 39779 457879 504404 541994 584278 645876 782704 928134
2)我想对所有这些目录进行排序和分组,并将其移动到 50000 的特定范围内。
例如:从 0 到 50000 的目录应移到 50000 下,50001 到 100000 的目录应移到 100000 下,依此类推。迭代次数应为 50000
我不是 shell 脚本专家:
这是我的 shell 脚本:
#!/bin/bash
#set -x
#Please pass document library path
SOURCE=/opt/dms/
DEST=/opt/nes_dms
cd $SOURCE
ls | sort -n >> /opt/ncm/list.txt
for dir in `cat /opt/ncm/list.txt`
do
#echo $dir
if [ "$dir" -le "50000" ]
then
echo $dir is less then $i
mv $dir $DEST
fi
done
我需要脚本自动递增 50000+50000=100000,并将 100000 目录中 50001 到 100000 之间的所有目录移动,直到我们读取文件中的所有目录。
答案1
#!/bin/bash
#set -x
#Please pass document library path
SOURCE='/crypto/home/hl/tmp/stackexchange/dir_groups/source'
DEST='/crypto/home/hl/tmp/stackexchange/dir_groups/target'
declare -a target_dir_indexes
cd "$SOURCE" || exit 1
for dir in *; do
test "$DEBUG" = 'yes' && echo "$dir"
test -d "$dir" && ! test -L "$dir" || continue
if ! [[ "$dir" =~ ^(0|[1-9][0-9]*)$ ]]; then
echo "error: dir name '${dir}'; skipping"
continue
fi
target_index=$((dir/50000))
if [ "$dir" -gt 0 ]; then
if [ $((dir%50000)) -eq 0 ]; then
((target_index--))
fi
fi
target_dir_name=$(((target_index+1)*50000))
target_dir_path="${DEST}/${target_dir_name}"
# avoid unneccessary calls to mkdir or the VFS
if [ -z "${target_dir_indexes[target_index]}" ]; then
mkdir -p "$target_dir_path"
target_dir_indexes[target_index]=1
fi
echo "${dir} is moved to ${target_dir_name}"
mv -i "$dir" "$target_dir_path"
done
答案2
数学有点棘手。简单的整数除法(file/50000+1)*50000
将会失败。如果文件编号为 50000,则结果为 100000。这不是您想要的。我们需要改变原点:
$(( ((file-1)/50000+1)*50000 ))
另外,更简单的代码方案也可以:
#!/bin/bash
fsource=/opt/dms; fdest=/opt/nes_dms; istep=50000
cd "$fsource"
for f In *; do
i=$(( 1+(f-1)/istep )) # Which bucket?
fd="$fdest/$(( istep*i ))"
echo \
mv -t "$fd" "$f"
done
添加一些检查[(是目录?)和(仅数字)]:
#!/bin/bash
fsource=/opt/dms/; fdest=/opt/nes_dms; istep=50000
for f in "$fsource"/*; do
[[ -d $f ]] || continue # Is a dir?
i=${f##*/} # Remove path.
[[ $i =~ ^[0-9]+$ ]] || continue # Only digits?
i=$((1+(i-1)/istep)) # Which bucket?
fd="$fdest/$(( istep*i ))"
echo \
mv -t "$fd" "$f"
done
当您对这些值感到满意并且想要执行移动时,请注释掉回显。
答案3
警告:当目录不是数字命名时,下面的脚本不会处理错误。
可能的解决方案:
#!/bin/bash
#set -x
SOURCE=/opt/dms/
DEST=/opt/nes_dms
for dir in `ls $SOURCE | sort -n`
do
# define destination subdir
dst_dir=$(( (($dir/50000) + 1) * 50000 ))
# check if destination subdir exists
if [ ! -d $DEST/$dst_dir ]
then
mkdir $DEST/$dst_dir
fi
mv $SOURCE/$dir $DEST/$dst_dir
done