Bisakah saya membuat `du` dikelompokkan berdasarkan bulan?

14

Saya memiliki direktori dengan banyak foto di dalamnya. Secara khusus, du -sh --apparent-size /path/to/myfolderberi saya 331G. Bagus sekali. Tetapi sekarang saya ingin mendapatkan daftar yang dikelompokkan berdasarkan bulan, misalnya sesuatu seperti ini:

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

Apakah ada cara (masuk akal) untuk melakukan ini dengan linux builtin, atau haruskah saya menulis utilitas Python sendiri untuk melakukannya?

Wayne Werner
sumber
1
Linux tidak memiliki builtin , ini adalah kernel sistem operasi. Apakah maksud Anda dengan perintah yang ditemukan secara default di beberapa sistem operasi berbasis Linux (seperti Debian, Fedora, ChromeOS ...) ?
Stéphane Chazelas
8
Kernel Linux adalah kernel linux, dan jika saya maksud linux kernel builtins saya akan mengatakan itu. Jika Anda harus bertele-tele, maksud saya seperangkat alat umum yang secara statistik Anda mungkin telah instal dengan instalasi default dari salah satu dari 5 distro linux teratas.
Wayne Werner
1
@WayneWerner Dengan kata lain, maksud Anda GNU / Linux, termasuk Bash, Coreutils, dan komponen inti lainnya dari lingkungan operasi GNU. #rmswasright
Damian Yerrick

Jawaban:

23

Di linux, coba:

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

Bagaimana itu bekerja

  • find /my/path

    Ini mencari file di dalam / my / path.

  • -maxdepth 1

    Ini memberitahu finduntuk tidak melihat ke subdirektori. (Jika Anda ingin pencarian rekursif, maka abaikan opsi ini.)

  • -type f

    Ini memberitahu finduntuk membatasi pencarian ke file biasa.

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

    Ini memberitahu finduntuk mencetak tahun-bulan diikuti oleh ukuran dalam byte untuk setiap file.

    Karena kami tidak menggunakannya, nama-nama file yang ditemukan tidak dicetak.

  • b[$1]+=$2

    Untuk setiap file yang ditemukan, kami menambahkan jumlah byte-nya, ditemukan dari kolom 2, ke jumlah yang kombinasi tahun-tahun dalam array asosiatif b.

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

    Setelah kami memproses semua hasil dari find, kami mencetak hasilnya.

  • sort

    Ini mengurutkan hasil dalam urutan tanggal.

Versi beberapa baris

Bagi mereka yang lebih suka kode mereka tersebar di beberapa baris:

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

Contoh

Mari kita pertimbangkan direktori dengan file-file ini:

$ 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

Output dari perintah kami adalah:

$ 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

Perbaikan

Jika kita menginginkan output dalam mebibytes (MiB) alih-alih byte, kita dapat mengonversi unit-unit seperti ini:

$ 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

Kita masih bisa lebih mengontrol format output dengan menggunakan printf. Di sini, untuk menjaga hanya satu digit setelah titik desimal, kami memformat ukurannya dengan %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
John1024
sumber
Ini fantastis. Bisakah Anda merekomendasikan tutorial awk? Saya belum menemukan satu yang belum membuat mata saya menyilang dalam waktu sekitar dua puluh detik.
hBy2Py
1
@ hBy2Py Pengantar favorit saya untuk awk, meskipun sekarang sedikit tanggal, adalah tutorial Grymoire .
John1024
saya sarankan menggunakan printf "%s %9d\n", date, b[date]alih-alih print date, b[date]menambahkan bantalan ruang ke kolom kedua
rav_kr
@rav_kr Ide bagus. Saya baru saja memperbarui jawaban dengan contoh yang digunakan printf.
John1024
FWIW jika Anda memiliki finddukungan itu, -maxdepthAnda mungkin memiliki [g]awkdukungan ituPROC_INFO["sorted_in"]="@ind_str_asc"
dave_thompson_085