unix系でファイルの数、容量を知りたい


unixコマンドのメモ

<追記 2015/7/16>
・ du/xargs/awk でなんでファイルサイズが変わってしまうのかについて記載

1.ファイル生成時刻の期間で抽出したい

たとえば、「2015-01-01」〜「2015-08-01」までで作成されたファイルの一覧がほしいとした場合、findコマンドを使用します。

期間抽出1つ目の方法

find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" 

-type f:ファイルだけに限定
-newerXY:(X=m)ファイルが更新された時間(Y=t)直接的な時刻指定として解釈
 =>「!」や「-not」といれれば 終点を見てくれる(-olderっていうのはない)

ただし、-newerXY の期間を直接書くことができる引数が使えるのはどうやらFreeBSD系。CentOSとか使えない場合はその期間用のダミーファイルを作って判定するしか無いみたいです。

期間抽出の2つ目の方法

touch -t 201501010000.00 /tmp/find_20150401 
touch -t 201508010000.00 /tmp/find_20150801
find . -type f -newer /tmp/find_20150401 ! -newer /tmp/find_20150801 

touchで空ファイルを時間指定して作る
-newer 時間指定したファイル名 で期間抽出する

2.ファイルの数を知りたい

findで実行した結果のファイル数を知りたい場合 wcコマンドを使います。

find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" | wc

3.ファイル全容量を知りたい

findで実行した結果のファイル容量を知りたい場合 awkやxargsなんかで容量を知ることができます。

awkで容量を計算してみる

こっちの方が安心して容量がわかります。

find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" -ls | awk '{sum +=$7;} END {printf("%d \n",sum)}'

-ls:find抽出結果をlsの形で表示してくれる
 =>容量は7番目に記載されている
|:パイプでつなげて、抽出結果を利用する
{sum +=$7;}:抽出結果の表示7番目をsum変数に加算していく
END {printf("%d \n",sum)}:最後にsumを表示させる

これで容量の総合計が出てきます!

xargsで容量を計算してみる

<注意> 抽出結果が多い場合はまります!!

find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" | xargs wc

xargsで実行した場合、ファイルごとに容量が標準出力に表示されます。
終わったと思ったときに出てくる「total」
「 1036184 6958743 305922107 total」<=こんな感じのやつ
awkの結果と同じになるはずなのに、ファイル数が多いと標準出力で出てきた結果が何故か違う気がする。
これ、何か少ないと感じた場合、見逃した「total」があるはずです。
実は複数回実行されているようなのです。

<確認してみる>

env LANG=C find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" |xargs env LANG=C wc > /tmp/ooooo
grep total /tmp/ooooo

env LANG=C:文字コードがおかしくないか統一させてみた
 > /tmp/ooooo:結果をファイルにおとしてみた
grep結果を見ると「total」が何回か出てくるはず。。。

私の結論!!
ファイルの容量を調べるときはawkを使おう

du/xargs/awk でなんでファイルサイズが変わってしまうのか

duを使う方法での前置き

findの結果を利用して容量計算のコマンドduを使いたい時、
man find を調べると -exec command {} + がありました!
この中の説明に
The command line is built in much the same way that xargs builds its command lines.
こんな記述がありました。結局xargsと同じ結果になるようです。

本題

$find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" -ls | awk '{sum +=$7;} END {printf("%d \n",sum)}'
$find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" | xargs wc
$ find . -type f -newermt "2015-01-01" ! -newermt "2015-08-01" -exec du -ch {} + 

上記の結果は一見全部同じようになるんじゃないかと思ってしまいましたが、
ファイルが沢山ころがっているようなフォルダ内で実行してみると結果がかなり違うことがわかります。

duやxargsはファイルのブロック数を表示しています。
なので、単純にファイル容量を計算したい場合は正しい結果がでません。

例)2byteのファイルを作ったから、lsやwcは2byteで表示されるけど、
duだと4kbになっちゃってるのを確認

$ echo a > /tmp/test
$ls -l /tmp/test
-rw-rw-r-- 1 user group 2 Jul 16 15:02 /tmp/1
$wc -c /tmp/test
2 /tmp/1
$du -ch /tmp/test
4.0K    /tmp/test
4.0K    total

これが積み重なったら、確かに容量数はくずれますよね。
また、「xargsで実行した場合に複数回実行されているみたい。」と記載しましたが、
この複数回実行されちゃうことも容量が正しく計算されない要因になります。
(複数回実行されちゃうのがわかるのは totalが複数回でてくるから)

ということで私の結論はやっぱり
「ファイルの容量を調べるときはawkを使おう」
です。

ただし、awkを使用する場合も、lsで表示されている7番目の列の数字を計算させています。
これが、権限がない場合やデバイスファイル(Character special file.やBlock special file.)の場合、容量の部分が表示されていなかったり、0になっていたりしています。
そうなると計算出来ないから意図しない容量数が出てしまうでしょう。
そこは気をつけましょう。。