Posso ottenere un `du` raggruppato per mese?


14

Ho una directory con molte foto. In particolare, du -sh --apparent-size /path/to/myfoldermi dà 331G. Che è grandioso. Ma ora voglio ottenere un elenco raggruppato per mese, ad esempio qualcosa del genere:

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

C'è un modo (ragionevole) per farlo con i builtin di Linux, o dovrei semplicemente scrivere la mia utility Python per farlo?


1
Linux non ha builtin , è un kernel del sistema operativo. Intendi con i comandi trovati di default in alcuni sistemi operativi basati su Linux (come Debian, Fedora, ChromeOS ...) invece?
Stéphane Chazelas,

8
Il kernel Linux è il kernel linux, e se intendessi i builtin del kernel linux lo avrei detto. Se devi essere pedante, intendo l'insieme generale di strumenti che statisticamente è probabile che tu abbia installato con un'installazione predefinita di una delle prime 5 distribuzioni Linux.
Wayne Werner,

1
@WayneWerner In altre parole, intendi GNU / Linux, inclusi Bash, Coreutils e altri componenti fondamentali dell'ambiente operativo GNU. #rmswasright
Damian Yerrick,

Risposte:


23

Su Linux, prova:

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

Come funziona

  • find /my/path

    Questo cerca i file in / my / path.

  • -maxdepth 1

    Questo dice di findnon guardare nelle sottodirectory. (Se si desidera una ricerca ricorsiva, omettere questa opzione.)

  • -type f

    Questo dice finddi limitare la ricerca a file regolari.

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

    Questo dice finddi stampare l'anno-mese seguito dalla dimensione in byte per ciascun file.

    Dal momento che non li utilizziamo, i nomi dei file trovati non vengono stampati.

  • b[$1]+=$2

    Per ogni file trovato, aggiungiamo il conteggio dei byte, trovato dalla colonna 2, al conteggio della combinazione anno-mese nella matrice associativa b.

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

    Dopo aver elaborato tutto l'output da find, stampiamo i risultati.

  • sort

    Questo ordina i risultati in ordine di data.

Versione a più righe

Per coloro che preferiscono il loro codice distribuito su più righe:

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

Esempio

Consideriamo una directory con questi file:

$ 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

L'output del nostro comando è:

$ 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

perfezionamenti

Se vogliamo l'output in mebibytes (MiB) anziché in byte, possiamo convertire le unità in questo modo:

$ 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

Possiamo ottenere ancora più controllo sul formato di output usando printf. Qui, per mantenere solo una cifra dopo il punto decimale, formattiamo la dimensione con %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

È fantastico. Puoi consigliare qualche tutorial su Awk? Non ne ho ancora trovato uno che non mi abbia fatto incrociare gli occhi in circa venti secondi.
hBy2Py,

1
@ hBy2Py La mia introduzione preferita a awk, anche se ora è un po 'datata, è il tutorial di Grymoire .
Giovanni 1024

suggerisco di utilizzare printf "%s %9d\n", date, b[date]invece di print date, b[date]aggiungere lo spazio di riempimento alla seconda colonna
rav_kr

@rav_kr Buona idea. Ho appena aggiornato la risposta con un esempio che utilizza printf.
Giovanni 1024

FWIW se si dispone findche supporta -maxdepthvoi probabilmente avere [g]awksupportatiPROC_INFO["sorted_in"]="@ind_str_asc"
dave_thompson_085
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.