FIETS ~インフラエンジニアトレーニング場~

24歳までIT音痴・PC嫌いだった人間が、インフラエンジニアとして食べていけるようになるまでに役に立った情報を掲載

[Linux] duの結果の合算値を出したい

 

 

悩み


正規表現で対象絞った際にduの結果を合計する方法

 

 

悩み詳細


ディレクトリ以下全てが対象であれば、 例1)のように-s(--summarize)オプションで合計がでます。
が、その中で対象ファイルを絞った上で、合計を出せるようになったら便利!


例1)

#下記のようなディレクトリ構造の場合に
$ ls /tmp/fiets/
10test 6test 7test 8test 9test test1 test2 test3 test4 test5

#ディレクトリに対してduコマンドを実行すれば、ディレクトリ以下のサイズの合計が表示される
$ du -s /tmp/fiets
10240044 /tmp/fiets

 

しかし、配下の複数ファイルに対して実行した場合は、合計の計算が別途必要...

ディレクトリ以下全てであれば、 例1) のようにディレクトリに対する実行でいいですが、 例2) のようにフィルタかけて絞りたい場合に困りました)

 

例2)

$ du -s /tmp/fiets/test*
1024004 /tmp/fiets/test1
1024004 /tmp/fiets/test2
1024004 /tmp/fiets/test3
1024004 /tmp/fiets/test4
1024004 /tmp/fiets/test5

 

 

解決方法

1.恒例の力技編

一応できたけど...長いしもっと良い方法ありそうだなーと思ってました。

duの結果をawkで一列目だけ取得し、それを配列に入れてからfor文ですべて足すように回す。。。なんて面倒な。

$ SUM=0;a=`du -s /tmp/fiets/test* |awk '{print $1}'`;a=(`echo $a`);for i in ${a[@]};do SUM=$(($SUM+$i));done;echo $SUM
5120020

 

2.awkで工夫したbetter編

awk演算子があり、もちろん四則演算もできるので、表示したものを片っ端から足していき、最後に表示。

$ du -s /tmp/fiets/test* | awk '{sum+=$1} END {print sum}'
5120020

 

3. -c(--total)オプションを利用したbest編

っ!?てかこんなのありましたわ!!

 

-c(--tota) : 総計を表示する 

$ du -c /tmp/fiets/test*
1024004 /tmp/fiets/test1
1024004 /tmp/fiets/test2
1024004 /tmp/fiets/test3
1024004 /tmp/fiets/test4
1024004 /tmp/fiets/test5
5120020 合計

 

やはり知ってるだけで楽になる知識ってありますね!(2回目の登場)

 

※1回目はこちら 

fiets.hateblo.jp

 

 

豆知識

ディレクトリ以下合計値を出すとき、4KBだけ大きい?

ディレクトリごとdu -sで計算する 例3) の場合と、
ディレクトリ以下のファイルのサイズを合算する 例4) の場合とで、4KB違うのはなぜでしょう。

 

例3)

$ du -s /tmp/fiets
10240044 /tmp/fiets

 vs 

例4)

$ du -c /tmp/fiets/*
1024004 /tmp/fiets/10test
1024004 /tmp/fiets/6test
1024004 /tmp/fiets/7test
1024004 /tmp/fiets/8test
1024004 /tmp/fiets/9test
1024004 /tmp/fiets/test1
1024004 /tmp/fiets/test2
1024004 /tmp/fiets/test3
1024004 /tmp/fiets/test4
1024004 /tmp/fiets/test5
10240040 合計

 

ここで!それぞれバイト単位の出力に変更してみましょう。

-bオプションを付けると、出力がKB(default)→B単位になります。

#ディレクトリに対するコマンド(ディレクトリごとまるっと合計値)
$ du -sb /tmp/fiets
10485764096 /tmp/fiets
vs 
#ディレクトリ以下のファイルの合算値

$ du -cb /tmp/fiets/*
1048576000 /tmp/fiets/10test
1048576000 /tmp/fiets/6test
1048576000 /tmp/fiets/7test
1048576000 /tmp/fiets/8test
1048576000 /tmp/fiets/9test
1048576000 /tmp/fiets/test1
1048576000 /tmp/fiets/test2
1048576000 /tmp/fiets/test3
1048576000 /tmp/fiets/test4
1048576000 /tmp/fiets/test5
10485760000 合計

正確には4096バイト差がありますね。なぜでしょう?


これはディレクトリ自体のサイズが入っているからです。
ディレクトリ自体のサイズは、ブロックサイズという大きさの単位で増えていき、最小でも1ブロックサイズを有します。

 

ブロックサイズの確認方法はファイルシステムによって変わります。
・CentOS6以下のext2,3であれば、tune2fs

# tune2fs -l /dev/mapper/VolGroup-lv_root | grep "Block size"
Block size: 4096

 

・CentOS7以降標準のxfsファイルシステムであれば xfs_info

# xfs_info /dev/mapper/cl-root | grep bsize | grep data
data = bsize=4096 blocks=117720064, imaxpct=25

 

ディレクトリ自体のサイズは何で変わる?

 上で、ディレクトリはブロックサイズ単位で増えていくと書きましたが、何に起因して増大していくのでしょうか?

それは中身のサイズの総計。ではなく、ファイル数になります。

今ぱっとファイル数多そうなディレクトリを見に行きましたが、下記のようなディレクトリサイズがありました。たしかに4096が単位ですね。なるほど。

 

12288 (4096*3)
53248 (4096*13)

 

 

参考


Man page of DU

Man page of GAWK