web-dev-qa-db-ja.com

月ごとにグループ化された「du」を取得できますか?

たくさんの写真が入ったディレクトリがあります。具体的には、du -sh --apparent-size /path/to/myfolderは331Gをくれます。それは素晴らしいです。しかし、今月ごとにグループ化されたリストを取得したいと思います。このようなもの:

2016-01   20MB
2016-02  520MB
2016-03  312MB
...

Linuxビルトインでこれを行う(合理的な)方法はありますか、それとも、独自のPythonユーティリティを作成して実行する必要がありますか?

14
Wayne Werner

Linuxでは、次のことを試してください。

_find /my/path -maxdepth 1 -type f -printf '%TY-%Tm %s\n' | awk '{b[$1]+=$2} END{for (date in b) print date, b[date]}' | sort
_

使い方

  • _find /my/path_

    これは/ my/pathでファイルを探します。

  • _-maxdepth 1_

    これはfindにサブディレクトリを調べないように指示します。 (再帰的な検索が必要な場合は、このオプションを省略してください。)

  • _-type f_

    これはfindに検索を通常のファイルに限定するように伝えます。

  • _-printf '%TY-%Tm %s\n'_

    これは、findに、年月を出力し、その後に各ファイルのサイズをバイト単位で出力するように指示します。

    それらを使用しないため、見つかったファイルの名前は出力されません。

  • _b[$1]+=$2_

    見つかったファイルごとに、列2から見つかったそのバイト数を、連想配列bのその年と月の組み合わせの数に追加します。

  • END{for (date in b) print date, b[date]}

    findからのすべての出力を処理した後、結果を出力します。

  • sort

    これにより、結果が日付順にソートされます。

複数行バージョン

複数行にまたがるコードを好む人のために:

_find /my/path -maxdepth 1 -type f -printf '%TY-%Tm %s\n' |
  awk '
    {
      b[$1]+=$2
    }

    END{
      for (date in b)
        print date, b[date]
    }
    ' | sort
_

これらのファイルを含むディレクトリを考えてみましょう:

_$ ls -l
total 27816
-rw------- 1 john1024 john1024 2459173 Nov 23  2015 img100.jpg
-rw------- 1 john1024 john1024 3479750 Nov 23  2015 img101.jpg
-rw------- 1 john1024 john1024 4028939 Nov 23  2015 img102.jpg
-rw------- 1 john1024 john1024 2928519 Jul 30 18:55 img103.jpg
-rw------- 1 john1024 john1024 2948294 Jul 30 18:55 img104.jpg
-rw------- 1 john1024 john1024 3177583 Aug  1 16:56 img105.jpg
-rw-rw---- 1 john1024 john1024 3111737 Apr 18  2016 img106.jpg
-rw-rw---- 1 john1024 john1024 1441310 Apr 18  2016 img107.jpg
-rw-rw---- 1 john1024 john1024 2430158 Apr 25 16:26 img108.jpg
-rw-rw---- 1 john1024 john1024 2424504 Apr 25 16:26 img109.jpg
_

コマンドの出力は次のとおりです。

_$ find . -maxdepth 1 -type f -printf '%TY-%Tm %s\n' | awk '{b[$1]+=$2} END{for (date in b) print date, b[date]}' | sort
2015-11 9967862
2016-04 9407709
2016-07 5876813
2016-08 3177583
_

洗練

バイトではなくメビバイト(MiB)で出力したい場合は、次のように単位を変換できます。

_$ find . -maxdepth 1 -type f -printf '%TY-%Tm %s\n' | awk '{b[$1]+=$2} END{for (date in b) print date, b[date]/1024**2, "MiB"}' | sort
2015-11 9.50609 MiB
2016-04 8.97189 MiB
2016-07 5.60457 MiB
2016-08 3.03038 MiB
_

printfを使用すると、出力フォーマットをさらに詳細に制御できます。ここでは、小数点以下1桁を維持するために、サイズを_%5.1f_でフォーマットします。

_$ find . -maxdepth 1 -type f -printf '%TY-%Tm %s\n' | awk '{b[$1]+=$2} END{for (date in b) printf "%s %5.1f MiB\n", date, b[date]/1024**2}' | sort
2015-11   9.5 MiB
2016-04   9.0 MiB
2016-07   5.6 MiB
2016-08   3.0 MiB
_
24
John1024