¿Existe una herramienta estándar? que convierte un número entero de bytes en un número legible por humanos del tamaño de unidad más grande posible, manteniendo el valor numérico entre 1,00 y 1023,99 ?
Tengo mi propio script bash/awk, pero estoy buscando un estándar herramienta, que se encuentra en muchas/la mayoría de las distribuciones... algo más generalmente disponible, e idealmente tiene argumentos de línea de comando simples, y/o puede aceptar entrada canalizada.
Estos son algunos ejemplos del tipo de salida que estoy buscando.
1 Byt
173.00 KiB
46.57 MiB
1.84 GiB
29.23 GiB
265.72 GiB
1.63 TiB
Aquí está el bytes-humano script (usado para el resultado anterior)
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 )
}'
Actualizar Aquí hay una versión modificada de Gilles' guión, como se describe en un comentario a su respuesta .. (modificado para adaptarse a mi aspecto preferido).
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}'
Respuesta aceptada:
No, no existe tal herramienta estándar.
Desde GNU coreutils 8.21 (febrero de 2013, por lo que aún no está presente en todas las distribuciones), en Linux no integrado y Cygwin, puede usar numfmt
. No produce exactamente el mismo formato de salida (a partir de coreutils 8.23, no creo que pueda obtener 2 dígitos después de los puntos decimales).
$ numfmt --to=iec-i --suffix=B --padding=7 1 177152 48832200 1975684956
1B
173KiB
47MiB
1.9GiB
Muchas herramientas GNU antiguas pueden producir este formato y la ordenación GNU puede ordenar números con unidades desde coreutils 7.5 (agosto de 2009, tan presente en las distribuciones modernas de Linux no integradas).
Encuentro tu código un poco complicado. Aquí hay una versión awk más limpia (el formato de salida no es exactamente idéntico):
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}'
(Republicado de una pregunta más especializada)
Relacionado:¿Por qué nadie usa el verdadero shell de Bourne como /bin/sh?