Чи можу я отримати групу `du` за місяцями?


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 ...) ?
Стефан Шазелас

8
Ядро Linux - це ядро ​​Linux, і якби я мав на увазі вбудовані Linux ядра, я би сказав це. Якщо ви повинні бути педантичними, я маю на увазі загальний набір інструментів, які ви статистично вірогідно встановили, встановивши за замовчуванням будь-який із 5 найвищих дистрибутивів Linux.
Уейн Вернер

1
@WayneWerner Іншими словами, ви маєте на увазі GNU / Linux, включаючи Bash, Coreutils та інші основні компоненти операційного середовища GNU. #rmswasright
Damian Yerrick,

Відповіді:


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

    Це шукає файли в / мій / шлях.

  • -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

Це фантастично. Ви можете порекомендувати будь-які навчальні підручники? Я ще не знайшов жодного, який не змусив би моїх очей перетнутись протягом приблизно двадцяти секунд.
hBy2Py

1
@ hBy2Py Моє улюблене вступ до awk, хоча воно зараз трохи застаріло, - це підручник Grymoire .
John1024

Я пропоную використовувати printf "%s %9d\n", date, b[date]замість того, print date, b[date]щоб додавати пробіли у другій колонці
rav_kr

@rav_kr Гарна ідея. Я просто оновив відповідь прикладом, який використовує printf.
John1024

FWIW якщо у вас є такі find, -maxdepthто, ймовірно, у вас є [g]awkтакі підтримувачіPROC_INFO["sorted_in"]="@ind_str_asc"
dave_thompson_085
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.