猫の手なら貸せる

いろいろ共有できたらいいなとおもってます

treeコマンドでディレクトリ容量を表示

だいぶ頑張って作りました。疲れました。

treeコマンドで--du(だったっけ)オプションを設定しても、ディレクトリ自体の容量(だいたい4KB)しか表示されず、統計を取得するのに困っていたので、treeをしつつduできるようなbash書きました。

なんでこんなに長ったらしくなったかと言いますと、私がmacOS使っているからなのかduで取得できたファイル名に忌むべし\rが入ってるくせにfindコマンドでは\n扱いだったりしたからです。Windowsだと\r\nになってもう手が追えません。試してませんが。

echoを使うと\nが無視されり\rが置き換わったりするのを利用してます。仕様の穴だとおもうので互換性ほとんどないかと思われます。動作環境はLinux version 4.19.93-v7lです。Raspbian Busterなら(同じ環境だし)(多分)動きます。

もっといい方法あると思います。私は疲れました。使い方。

  1. ソースコードをtreedu.shとして保存します。
  2. 第一引数に調べたいディレクトリ、第二引数にmax-depthを設定します。
  3. 標準出力にtreeの結果が出てきます。
#!/bin/bash

if [ $? -ne 2 ];then 
    echo "Set directory, depth. ex: ./treedu.sh /home/nkhnd 2"
    exit 1
fi
dir=${1%/}/
deps=$2

dirinfo=
msg=
dirs=`find ${dir} -maxdepth $deps -type d -exec echo {} \; 2>/dev/null`
IFS=$IFS_b
IFS=$'\n'
while read line;do
    dirinfo="${dirinfo}\n`du -sh $line`"
done <<END
$dirs
END
IFS=$IFS_b
trees=`/usr/bin/tree $dir -d -L $deps`
while read line;do 
    dirname=${line##* }
    dirsize=`echo -e "$dirinfo" | grep ${dirname} 2>/dev/null | head -1 | cut -f 1`
    if [ ${dirsize} != "" 2>/dev/null ] ;then
        msg="${msg}\n${line} [${dirsize}]" 
    else
        msg="${msg}\n${line}"
    fi
done <<END
$trees
END

echo -e ${msg:2}

変数弄りにはインターネッツを大いに参考にさせていただきました。

qiita.com

注意点としては、一つ一つのフォルダをdu -shしているので、でかいファイルだらけの環境ですとそこそこ時間がかかることです。

後、致命的なのですが同じ名前のディレクトリが存在すると誤った数値を表示します
ちょっと書き直せば直せるんですけど、自分の環境では、同じ名前のディレクトリはmax-depth 5とかじゃなければ出てこないので無視します。そもそもわかる範囲のdepthは4が限界だと思います。

直すヒントとしては、多分head -1ってなっているところをこう、どんくさい感じでうまくやればいけると思います。

以上、ねこでした。