我可以获得按月分组的“du”吗?

Way*_*ner 14 shell disk-usage files

我有一个目录,里面有很多照片。具体du -sh --apparent-size /path/to/myfolder给我331G。这很棒。但现在我想得到一个按月分组的列表,例如这样的:

2016-01   20MB
2016-02  520MB
2016-03  312MB
...
Run Code Online (Sandbox Code Playgroud)

有没有一种(合理的)方法可以使用 linux 内置函数来做到这一点,还是我应该编写自己的 Python 实用程序来做到这一点?

Joh*_*024 28

在 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
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • 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
Run Code Online (Sandbox Code Playgroud)

例子

让我们考虑一个包含这些文件的目录:

$ 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
Run Code Online (Sandbox Code Playgroud)

我们命令的输出是:

$ 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
Run Code Online (Sandbox Code Playgroud)

改进

如果我们想要以兆字节(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
Run Code Online (Sandbox Code Playgroud)

我们可以通过使用printf. 在这里,为了在小数点后只保留一位,我们将大小格式化为%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
Run Code Online (Sandbox Code Playgroud)