Come ordinare le dimensioni leggibili dall'uomo


11

Sto fondamentalmente cercando i file quindi ordinandoli per dimensione. Lo script funziona se non ordino le dimensioni in base alla lettura umana. Ma voglio che le dimensioni siano leggibili dall'uomo. Come posso ordinare formati leggibili dall'uomo?

Per esempio:

 ls -l | sort -k 5 -n | awk '{print $9 " " $5}'

Funziona come previsto, ho ottenuto la dimensione dei miei file in byte crescente:

1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850

Ora, voglio che le dimensioni siano leggibili dall'uomo, quindi ho aggiunto un parametro -h a ls, e ora alcuni file sono fuori servizio:

 ls -lh | sort -k 5 -n | awk '{print $9 " " $5}'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K


-k 5- come funziona?
ctrl-alt-delor,

@ ctrl-alt-delor: credo che la dimensione sia nella quinta colonna lsdell'output
jesse_b

2
Usare al duposto di lspotrebbe essere una buona idea.
xenoid,

... o finds' -printfcon la sua %pe %sformattatori (seguita da una ‘umanizzazione’ delle dimensioni).
Stephen Kitt,

@Jesse_b il mio errore, ho solo supposto che i dati nella domanda (contrassegnati come questo è quello che ho ottenuto) fosse l'input ordinato. Ho sbagliato.
ctrl-alt-delor,

Risposte:


28

Provare sort -h k2

-h, --human-numeric-sort confronta i numeri leggibili dall'uomo (es. 2K 1G)

Fa parte di gnu sort, BSD sort e altri.


5
L'analisi dell'output di non dovrebbe lsessere evitata?

3
@Tomasz Non sempre. Se fornisce l'output necessario, collegarlo a un'altra operazione di formattazione non è particolarmente pericoloso. Quello che non dovresti fare è passare in rassegna l'output di lse utilizzare invece il globbing dei file direttamente. Globbing da solo non funzionerà qui. Detto questo, probabilmente preferirei duquesto.
Bloodgain

1
@Bloodgain non è garantito che il formato ls sia lo stesso tra i binari di sistemi / ls, quindi analizzarlo in modo portabile è considerato impossibile.
D. Ben Knoble,

1
Inoltre, i nomi di file con spazi bianchi
mangeranno le

1
@Bloodgain: files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo ${#files[@]}(potrei avere un interruttore di prova symlink sbagliato). Se non ti interessano i link simbolici, files=(*); echo ${#files[@]}che diventano portatili se usi sete non array.
D. Ben Knoble,

29

lsha questa funzionalità integrata, usa l' -Sopzione e ordina in ordine inverso:ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first

1
-hnon è un'opzione standardls , ma deve essere utilizzabile se OP lo possiede già. Il resto è standard ed è sicuramente la risposta che avrei scritto.
Toby Speight,

5
+1 Non scherzare analizzando l'output di ls.
David Richerby,

Questa è la risposta migliore, ma dovrebbe includere le informazioni nel commento di @ Toby: -Spotrebbe non essere disponibile per te ls. FWIW, -Sè supportato anche con la libreria di Emacs ls-lisp.el, che viene utilizzata quando il sistema operativo non ha ls. Funziona in Emacs su MS Windows, per esempio.
Estratto il

Questa dovrebbe essere la risposta accettata.
disperde il

1
@Drew: il commento di Toby afferma che -hpotrebbe non essere universalmente disponibile, ma OP lo sta già utilizzando comunque. dovrebbe-S davvero essere universalmente disponibile, perché è nel collegamento POSIX fornito da Toby. Tuttavia, esistono alcuni toolkit non POSIX.
Kevin,

5

Poiché non è stata menzionata alcuna shell specifica, ecco come eseguire l'intera operazione nella zshshell:

ls -lhf **/*(.Lk-1024oL)

Il **modello glob corrisponde come *ma /nei nomi dei percorsi, cioè come farebbe una ricerca ricorsiva.

Il lscomando abiliterebbe le dimensioni leggibili dall'uomo con -he il formato di output dell'elenco lungo con -l. L' -fopzione disabilita l'ordinamento, quindi lsdovrebbe semplicemente elencare i file nell'ordine in cui sono stati dati.

Questo ordine è organizzato dal **/*(.Lk-1024oL)modello globbing del nome file in modo che i file più piccoli siano elencati per primi. Il **/*bit corrisponde a tutti i file e directory in questa directory e in basso, ma (...)modifica il comportamento del glob (è un "qualificatore glob").

È oLalla fine che ordina ( o) i nomi in base alla dimensione del file ( L, "lunghezza").

.L'all'inizio rende il glob corrisponde solo i file regolari (non directory).

Il Lk-1024bit seleziona i file di dimensioni inferiori a 1024 KB ("lunghezza in KB inferiore a 1024").

Se zshnon è la shell interattiva principale, è possibile utilizzare

zsh -c 'ls -lf **/*(.Lk-1024oL)'

Usa setopt GLOB_DOTS(o zsh -o GLOB_DOTS -c ...) per abbinare anche i nomi nascosti. ... o semplicemente aggiungi Dalla stringa di qualificazione glob.


Espandendo quanto sopra, presupponendo che si desideri un output a 2 colonne con nomi di percorso e dimensioni leggibili dall'uomo, e anche ipotizzando di avere numfmtda GNU coreutils,

zmodload -F zsh/stat b:zstat

for pathname in **/*(.Lk-1024oL); do
    printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done

o, più veloce,

paste <( printf '%s\n' **/*(.Lk-1024oL) ) \
      <( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )

4

Se il tuo sortnon ha l' -hopzione puoi usare un comando awk (anche se molto lungo) come il seguente:

find . -type f -size -1024k -exec ls -al {} \; | sort -k 5 -n | awk '{if ($5 > 1099511627776) {print $9,$5/1024/1024/1024/1024"T"} else if ($5 > 1073741824) {print $9,$5/1024/1024/1024"G"} else if ($5 > 1048576) {print $9,$5/1024/1024"M"} else if ($5 > 1024) {print $9,$5/1024"K"} else {print $9,$5"B"}}' | column -t

Questo ordinerà l'output in byte e successivamente li convertirà nella loro dimensione leggibile dall'uomo.


-1

Funzionerebbe?

ls -l | awk '{if ($5<=1024) {print}}' | sort -k 5 -n | awk '{print $9"\t"substr($5/1024,1,3)"k"} '| column -t

Il primo awkexp cercherà i file inferiori a 1M e il secondo prenderà la dimensione in byte dal risultato e lo convertirà in KB e stamperà i primi 3 elementi per dare una dimensione leggibile dall'uomo.


Questo non risolve davvero la domanda dei PO: guarda solo nella directory corrente e stampa solo file regolari. Inoltre confronterà con 1Kb invece di 1MB. Finalmente stiamo cercando delle risposte con alcune spiegazioni sul perché il codice funzioni.
grochmal,

Il mio male ha aggiunto quello che fa.
Vignesh SP,
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.