指定したディレクトリの中にある、ファイルの合計サイズを取得する方法

linuxコマンドのfindとawkを使って、指定したディレクトリに含まれるファイルの合計サイズを取得する方法を紹介します。また、findとawkの簡単な使い方についてもまとめてあります。

find, awkコマンドを簡単に紹介

まずは、findとawkコマンドを簡単に紹介します。あくまでも概要程度なので、詳しく知りたい場合は、man findman awkでご確認ください。

findコマンド

findはファイルやディレクトリを検索できるコマンドです。例えば以下のコマンドで、あるディレクトリ下の拡張子が.pngであるファイルを全て取得することができます。

# 「/tmp/foo/」下にあって、ファイル名が「*.png」(`-name "*png"`)の、ファイル(`-type f`)
$ find /tmp/foo/ -name "*.png" -type f

また、-execやパイプ「|」でつなげてxargsをすることによって、検索にヒットしたファイルやディレクトリに対して、何かしらの処理を実行することもできます。

例えば以下のコマンドで、「/tmp/foo/」以下の拡張子がpngのファイルを全て削除します。

$ find /tmp/foo/ -name "*.png" -type f -exec rm {} \;
OR
$ find /tmp/foo/ -name "*.png" -type f -print0 | xargs -0 --no-run-if-empty rm

awkコマンド

awkはレコードの1行1行に対して処理を実行できるプログラム言語です。awkの詳しい説明はウィキペディアなどをご確認いただければと思います。

今回は、awkを使って、ファイルサイズの合計を計算します。例えば、各カラムがスペースで区切られたテキストファイル「foo.txt」があるとします。

NAME1 2000
NAME2 2330
NAME3 58989

このファイルの2列目にある、2000, 2330, 58989の合計を計算したいときは、foo.txtと同じディレクトリで以下のコマンドを実行します。

$ cat foo.txt | awk 'BEGIN { sum = 0; } { sum += $2; } END { print sum; }'
63319

まずは、BEGIN { sum = 0; }で、変数「sum」に0を代入しています。※BEGINの部分がなくても動きますが、わかりやすいように付けています。

次に、{ sum += $2; }の部分です。この部分では、各行(「NAME1 2000」、「NAME2 2330」、「NAME3 58989」)に対して、sum += $2;という処理をしています。$2は、各行の2カラム目、つまり「2000」、「2330」、「58989」です。

そして、全ての行に対して{ sum += $2; }を実行したら、END { print sum; }sumの値を出力しています。

awkで計算するイメージ

特定ディレクトリ以下のファイルサイズを取得

findとawsを簡単に紹介したので、次は実際にファイルサイズを計算する方法に進みます。

findコマンドでファイルサイズを表示

先ほど、findを使うとファイルやディレクトリを検索できると書きました。その検索結果を、特定のフォーマットで出力することをできます。

例えば、/tmp/foo下に、以下の用にファイルが置かれているとします。

* foo1.txt
* foo2.txt
* bar/bar1.txt
* bar/bar2.txt

この時に、以下のように-printf "%p %s\n"をfindのオプションに指定すると、「ファイル名 サイズ」という形式で出力することができます。

$ find /tmp/foo/ -type f -printf "%p %s\n"
/tmp/foo/foo2.txt 300
/tmp/foo/bar/bar2.txt 4880
/tmp/foo/bar/bar1.txt 1005
/tmp/foo/foo1.txt 50

上記フォーマット、どこかで見覚えがないでしょうか?そう、先ほどawkの例で扱った

NAME1 2000
NAME2 2330
NAME3 58989

と同じですね!

findとawkでファイルサイズの合計を取得する

ここまできたら、後はfindとawkを組み合わせるだけです。以下のコマンドで、指定した調べるディレクトリのパス以下にある、ファイルの合計サイズを表示できます。

$ find <調べるディレクトリのパス> -type f -printf "%p %s\n" | awk 'BEGIN { sum = 0; } { sum += $2; } END { print sum; }'

例えば、/tmp/foo以下のファイルサイズの合計を計算したい場合は、

$ find /tmp/foo/ -type f -printf "%p %s\n" | awk 'BEGIN { sum = 0; } { sum += $2; } END { print sum; }'

となります。

不要な記述を省略

不要な部分を色々と省くと、以下のようになります。

$ find /tmp/foo/ -type f -printf "%s\n" | awk '{ sum += $1; } END { print sum; }'

※省いた部分

  • -printf%p
  • BEGINの変数宣言

備考

phpなどの中でファイルサイズを取得したい場合

findとawkをプログラム内から呼ぶことで、phpなどでもファイルサイズの合計を計算することができます。例えばphpの場合、execなどでコマンドでfindとawkを呼び出せます。

<?php
function get_filesize_from_dir($dirpath) {
    if (!is_dir($dirpath)) {
        throw new Exception(sprintf('ディレクトリ[%s]が存在しません。', $dirpath));
    }
    $cmd = '/bin/find '. $dirpath .' -type f -printf "%s\n" | /bin/awk \'{ sum += $1; } { print sum; }\'';
    $filesize = exec($cmd, $output, $return_var);
    if ($return_var !== 0) {
        throw new Exception('コマンドの実行に失敗しました。');
    }
    return $filesize;
}

echo 'filesize: ' . get_filesize_from_dir('/tmp/foo');

この記事が役に立った場合、シェアしていただけると励みになります!!