Esiste uno strumento standard che converte un numero intero di Byte in un conteggio leggibile dall'uomo della dimensione unitaria più grande possibile, mantenendo il valore numerico compreso tra 1,00 e 1023,99?
Ho il mio script bash/awk, ma sto cercando uno standard strumento, che si trova su molte/maggior parte delle distribuzioni... qualcosa di più generalmente disponibile, e idealmente ha semplici argomenti da riga di comando e/o può accettare input tramite pipe.
Ecco alcuni esempi del tipo di output che sto cercando.
1 Byt
173.00 KiB
46.57 MiB
1.84 GiB
29.23 GiB
265.72 GiB
1.63 TiB
Ecco il byte-umano script (usato per l'output sopra)
awk -v pfix="$1" -v sfix="$2" 'BEGIN {
split( "Byt KiB MiB GiB TiB PiB", unit )
uix = uct = length( unit )
for( i=1; i<=uct; i++ ) val[i] = (2**(10*(i-1)))-1
}{ if( int($1) == 0 ) uix = 1; else while( $1 < val[uix]+1 ) uix--
num = $1 / (val[uix]+1)
if( uix==1 ) n = "%5d "; else n = "%8.2f"
printf( "%s"n" %s%sn", pfix, num, unit[uix], sfix )
}'
Aggiorna Ecco una versione modificata di Gilles script, come descritto in un commento alla sua risposta ..(modificato per adattarsi al mio aspetto preferito).
awk 'function human(x) {
s=" B KiB MiB GiB TiB EiB PiB YiB ZiB"
while (x>=1024 && length(s)>1)
{x/=1024; s=substr(s,5)}
s=substr(s,1,4)
xf=(s==" B ")?"%5d ":"%8.2f"
return sprintf( xf"%sn", x, s)
}
{gsub(/^[0-9]+/, human($1)); print}'
Risposta accettata:
No, non esiste uno strumento standard del genere.
Da GNU coreutils 8.21 (febbraio 2013, quindi non ancora presente in tutte le distribuzioni), su Linux e Cygwin non embedded, puoi usare numfmt
. Non produce esattamente lo stesso formato di output (a partire da coreutils 8.23, non penso che tu possa ottenere 2 cifre dopo i punti decimali).
$ numfmt --to=iec-i --suffix=B --padding=7 1 177152 48832200 1975684956
1B
173KiB
47MiB
1.9GiB
Molti vecchi strumenti GNU possono produrre questo formato e l'ordinamento GNU può ordinare i numeri con le unità a partire da coreutils 7.5 (agosto 2009, così presente sulle moderne distribuzioni Linux non integrate).
Trovo il tuo codice un po' contorto. Ecco una versione awk più pulita (il formato di output non è esattamente identico):
awk '
function human(x) {
if (x<1000) {return x} else {x/=1024}
s="kMGTEPZY";
while (x>=1000 && length(s)>1)
{x/=1024; s=substr(s,2)}
return int(x+0.5) substr(s,1,1)
}
{sub(/^[0-9]+/, human($1)); print}'
(Ripubblicato da una domanda più specializzata)
Correlati:perché nessuno usa la vera shell Bourne come /bin/sh?