test1ディレクトリの中に、さらにディレクトリが入れ子になっている状況。 test1ディレクトリのサイズが大きいため、test1-2ディレクトリへtest1ディレクトリのサイズが半分になるようファイルを移動したい。
# ls -l test1 合計 4 drwxr-xr-x. 28 root root 4096 7月 28 16:51 2015 s # ls test1/s/ sa sb sc sd se sf sg sh si sj sk sl sm sn so sp sq sr ss st su sv sw sx sy sz
汎用性は考えずにとりあえず作りました。
#!/bin/bash path=./test1-2/s/ totalsize=`du -sm ./test1/s | cut -f 1` halfsize=$(($totalsize / 2)) ls ./test1/s/ | while read x do size=`du -sm ./test1/s/$x | cut -f 1` echo "size" $size echo "sum" $sum sum=$((sum + size)) # 合計が半分を超えていたら if [ $sum -gt $halfsize ]; then echo over # ディレクトリがない場合は作成する if [ ! -e $path ]; then mkdir -p $path fi # 移動させる mv ./test1/s/$x ${path} fi done
実行例
# du -sm ./* 1 ./test.sh 3801 ./test1 1 ./test2 1 ./test3 # ./test.sh size 101 sum size 101 sum 101 size 1101 sum 202 size 101 sum 1303 size 101 sum 1404 size 101 sum 1505 size 101 sum 1606 size 101 sum 1707 size 101 sum 1808 over (省略) size 101 sum 3321 over size 101 sum 3422 over size 101 sum 3523 over size 101 sum 3624 over size 101 sum 3725 over # du -sm ./* 1 ./test.sh 1801 ./test1 2001 ./test1-2 1 ./test2 1 ./test3
test1が1801Mbyte,test1-2が2001Mbyteとなり、大体半分に分割できました。
最初perlやawkで容量をsumしていけばワンライナーで出来ないか考えていたんですが、 perlやawk実行途中でmvどうやってするのかわからなくて辞めました。
サイズを足していくperl
du -sm ./test1/s/s* | cut -f 1 | perl -ne '$sum+=$_;END{print $sum}'
サイズを足していくawk
du -sm ./test1/s/s* | awk '{sum+=$1}END{print sum}'
と思っていたんですが、頑張ったらできました。
移動先ディレクトリ作成や全体の半分のサイズはあらかじめ出しておく必要がありますが。
awkで半分をオーバしたら、ファイル名を使ってmvコマンドを作成し、それをシェルに渡します。
du -sm ./test1/s/s* | awk '{sum+=$1;if(sum>1900){print "mv " $2 " ./test1-2/s/"}}'|sh # du -sm ./* 1 ./test.sh 1801 ./test1 2001 ./test1-2 1 ./test2 1 ./test3