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