我可以按月分组吗?


14

我的目录中有很多照片。具体来说,du -sh --apparent-size /path/to/myfolder给我331G。太好了 但是现在我想要按月分组的列表,例如:

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

是否有(合理的)方式使用linux内置函数来执行此操作,还是我应该编写自己的Python实用程序来执行此操作?


1
Linux没有内置插件,它是一个操作系统内核。您是说使用某些基于Linux的操作系统(例如Debian,Fedora,ChromeOS ...)中默认找到的命令吗?
斯特凡Chazelas

8
Linux内核是linux内核,如果我的意思是linux内核内置的话,我会这么说。如果您一定要学究,我指的是从统计上来说,您可能会安装的一般工具集以及默认安装的前5个Linux发行版中的任何一个。
韦恩·沃纳

1
@WayneWerner换句话说,您的意思是GNU / Linux,包括Bash,Coreutils和GNU操作环境的其他核心组件。#rmswasright
Damian Yerrick '16

Answers:


23

在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。在这里,为了保持小数点后一位数字,我们使用以下格式设置大小%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

这是太棒了。您可以推荐任何awk教程吗?我还没找到能在二十秒钟内使我的眼睛睁开的人。
hBy2Py

1
@ hBy2Py我最喜欢的awk入门,尽管它有些过时了,但它还是Grymoire教程
John1024 '16

我建议使用printf "%s %9d\n", date, b[date]而不是print date, b[date]在第二列中添加空格填充
rav_kr 16-10-19

@rav_kr好主意。我只是使用的示例更新了答案printf
John1024 '16

FWIW,如果您有find支持,-maxdepth可能会有[g]awk支持PROC_INFO["sorted_in"]="@ind_str_asc"
dave_thompson_085
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.