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이어야 합니다.
저는 쉘 스크립팅 전문가가 아닙니다.
이것은 내 쉘 스크립트입니다.
#!/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